/**
  * {@inheritdoc}
  */
 public function make(IdentityInterface $identity, EntityInterface $meta, CollectionInterface $data)
 {
     if (!$meta instanceof Relationship) {
         throw new InvalidArgumentException();
     }
     $reflection = (new ReflectionClass((string) $meta->class()))->withProperty($meta->identity()->property(), $identity)->withProperty($meta->startNode()->property(), $this->generators->get($meta->startNode()->type())->for($data->get($meta->startNode()->property())))->withProperty($meta->endNode()->property(), $this->generators->get($meta->endNode()->type())->for($data->get($meta->endNode()->property())));
     $meta->properties()->foreach(function (string $name, Property $property) use(&$reflection, $data) {
         if ($property->type()->isNullable() && !$data->hasKey($name)) {
             return;
         }
         $reflection = $reflection->withProperty($name, $property->type()->fromDatabase($data->get($name)));
     });
     return $reflection->buildObject();
 }
 private function isValidProperty(string $property, EntityInterface $meta) : bool
 {
     if ($meta->properties()->contains($property)) {
         return true;
     }
     return $meta->startNode()->property() === $property || $meta->endNode()->property() === $property;
 }
 private function translateRelationship($identity, EntityInterface $meta, ResultInterface $result) : CollectionInterface
 {
     $relationship = $result->relationships()->filter(function (RelationshipInterface $relationship) use($identity, $meta) {
         $id = $meta->identity()->property();
         $properties = $relationship->properties();
         return $properties->hasKey($id) && $properties->get($id) === $identity;
     })->first();
     $data = (new Collection([]))->set($meta->identity()->property(), $relationship->properties()->get($meta->identity()->property()))->set($meta->startNode()->property(), $result->nodes()->get($relationship->startNode()->value())->properties()->get($meta->startNode()->target()))->set($meta->endNode()->property(), $result->nodes()->get($relationship->endNode()->value())->properties()->get($meta->endNode()->target()));
     $meta->properties()->foreach(function (string $name, Property $property) use(&$data, $relationship) {
         if ($property->type()->isNullable() && !$relationship->properties()->hasKey($name)) {
             return;
         }
         $data = $data->set($name, $relationship->properties()->get($name));
     });
     return $data;
 }
 /**
  * {@inheritdoc}
  */
 public function extract($entity, EntityInterface $meta) : CollectionInterface
 {
     if (!$meta instanceof Relationship) {
         throw new InvalidArgumentException();
     }
     $refl = new ReflectionObject($entity);
     $data = $refl->extract([$id = $meta->identity()->property(), $start = $meta->startNode()->property(), $end = $meta->endNode()->property()]);
     $data = $data->set($id, $data->get($id)->value())->set($start, $data->get($start)->value())->set($end, $data->get($end)->value());
     $meta->properties()->foreach(function (string $name, Property $property) use(&$data, $refl) {
         $data = $data->set($name, $property->type()->forDatabase($refl->extract([$name])->get($name)));
     });
     return $data;
 }