public static function fromXml($xml)
 {
     $xpath = new DOMXpath($xml);
     $simulation = new static();
     $simulationNode = $xpath->query('//simulationDefinition/simulation')->item(0);
     $simulation->Id = strtoupper($simulationNode->getAttribute('id'));
     $simulationAttributes = ['Caption', 'SegmentationType', 'Progress', 'State', 'Color', 'Active'];
     foreach ($simulationAttributes as $simulationAttribute) {
         $simulation->{$simulationAttribute} = $simulationNode->getAttribute(strtolower($simulationAttribute));
     }
     //if (Simulation::find($simulation->Id))
     //  return [false, "Simulation with this ID already exists"];
     $simulationNeedle = [];
     $combination = Combination::find($xpath->query('//simulationDefinition/combination/@id')->item(0)->value);
     if (!$combination) {
         throw new Exception("Cannot find combination (you may be able to work around this manually from the XML)");
     }
     $patient = DB::table('ItemSet_Patient')->where('Id', '=', $xpath->query('//simulationDefinition/simulation/patient/@id')->item(0)->value)->get();
     if (empty($patient)) {
         throw new Exception("Patient no longer exists");
     }
     $patient = $patient[0];
     $simulation->Combination_Id = $combination->Combination_Id;
     $simulation->Patient_Id = $patient->Id;
     $simulation->Id = null;
     $simulation->save();
     $parameterNodes = $xpath->query('//simulationDefinition/parameters/parameter');
     $parameters = [];
     foreach ($parameterNodes as $parameterNode) {
         $parameter = Parameter::whereName($parameterNode->getAttribute("name"))->first();
         $simulation->Parameters()->attach($parameter, ["ValueSet" => $parameterNode->getAttribute("value")]);
     }
     $needleNodes = $xpath->query('//simulationDefinition/numericalModel/needles/needle');
     foreach ($needleNodes as $needleNode) {
         $needle = Needle::find($needleNode->getAttribute("id"));
         if (!$needle) {
             throw new Exception("Needle not found");
         }
         $simulationNeedle = new SimulationNeedle();
         $simulationNeedle->Needle_Id = $needle->Id;
         $simulationNeedle->Simulation_Id = $simulation->Id;
         $simulationNeedle->save();
         $parameterNodes = $xpath->query('//simulationDefinition/numericalModel/needles/needle/parameters/parameter');
         $parameters = [];
         foreach ($parameterNodes as $parameterNode) {
             $parameter = Parameter::whereName($parameterNode->getAttribute("name"))->first();
             switch ($parameter->Name) {
                 case "NEEDLE_TIP_LOCATION":
                     $target = PointSet::fromArray(json_decode($parameterNode->getAttribute("value")));
                     $target->save();
                     $simulationNeedle->Target_Id = $target->Id;
                     break;
                 case "NEEDLE_ENTRY_LOCATION":
                     $entry = PointSet::fromArray(json_decode($parameterNode->getAttribute("value")));
                     $entry->save();
                     $simulationNeedle->Entry_Id = $entry->Id;
                     break;
                 default:
                     $simulationNeedle->Parameters()->attach($parameter, ["ValueSet" => $parameterNode->getAttribute("value")]);
             }
         }
         $simulationNeedle->save();
     }
     //foreach ($parameters as $sP)
     //{
     //  $sP->Simulation_Id = $simulation->Id;
     //  $sP->save();
     //}
     $simulation->save();
     return $simulation;
 }
 public function duplicate($id)
 {
     $oldSimulation = Simulation::find($id);
     $simulation = new Simulation();
     $simulation->Combination_Id = $oldSimulation->Combination_Id;
     $simulation->Patient_Id = $oldSimulation->Patient_Id;
     if (Input::get('caption')) {
         $simulation->Caption = Input::get('caption');
     } else {
         $simulation->Caption = $oldSimulation->Caption . '+';
     }
     if (substr($simulation->Caption, 0, 2) != "N:") {
         $simulation->Caption = "N: " . $simulation->Caption;
     }
     $simulation->SegmentationType = $oldSimulation->SegmentationType;
     $simulation->Progress = '0';
     $simulation->State = 0;
     $simulation->Color = 0;
     $simulation->Active = 0;
     $simulation->Original_Id = $oldSimulation->Id;
     $simulation->Parent_Id = $oldSimulation->Parent_Id;
     $simulation->save();
     $oldSimulation->SimulationNeedles->each(function ($needle) use($simulation) {
         $simulationNeedle = new SimulationNeedle();
         $simulationNeedle->Needle_Id = $needle->Needle_Id;
         $simulationNeedle->Target_Id = PointSet::create(['X' => $needle->Target->X, 'Y' => $needle->Target->Y, 'Z' => $needle->Target->Z])->Id;
         $simulationNeedle->Entry_Id = PointSet::create(['X' => $needle->Entry->X, 'Y' => $needle->Entry->Y, 'Z' => $needle->Entry->Z])->Id;
         $simulationNeedle->Index = $needle->Index;
         $simulationNeedle->Simulation_Id = $simulation->Id;
         $simulationNeedle->save();
         $needle->Parameters->each(function ($parameter) use($simulationNeedle) {
             $simulationNeedle->Parameters()->attach($parameter, ['ValueSet' => $parameter->pivot->ValueSet, 'Format' => $parameter->pivot->Format, 'Editable' => $parameter->pivot->Editable]);
         });
     });
     $oldSimulation->Parameters->each(function ($parameter) use($simulation) {
         $simulation->Parameters()->attach($parameter, ['ValueSet' => $parameter->pivot->ValueSet, 'Format' => $parameter->pivot->Format, 'Editable' => $parameter->pivot->Editable]);
     });
     if (Config::get('gosmart.integrated_patient_database')) {
         DB::table('ItemSet')->insert(['CreationDate' => date('Y-m-d H:i:s'), 'IsDeleted' => false, 'Id' => $simulation->Id]);
     }
     if (Response::json()) {
         return Simulation::find($simulation->Id);
     }
     return Redirect::route('simulation.edit', $simulation->Id);
 }