public function toDataTransferObject($root, $schema, $transformations, $path='')
    {
        $dto = new DataTransferObject();

        // get morphed schema
        if($this->morphClass) {
            $morphKey = '...'.Str::studly($this->morphClass);
            if (isset($schema[$morphKey])) {
                $schema = $schema[$morphKey];
            }
        }

        foreach ($schema as $key => $value) {
            // entry is attribute
            if (is_numeric($key)) {
                // transformation key
                $transformationKey = ($path)
                    ? $root.'.'.$path.'.'.$value
                    : $root.'.'.$value;

                // set value
                if ($value == '__type') {
                    $dto->{$value} = class_basename($this->class);
                } elseif (isset($transformations[$transformationKey])) {
                    $node = new GraphNode;
                    $transformations[$transformationKey]($node, $this->attributes);
                    $dto->{$value} = $node->getValue();
                } elseif (isset($transformations['*.'.$value])) {
                    $node = new GraphNode;
                    $transformations['*.'.$value]($node, $this->attributes);
                    $dto->{$value} = $node->getValue();
                } else {
                    $columnName = $this->getColumnName($value);
                    if (isset($this->attributes[$columnName])) {
                        $dto->{$value} = $this->attributes[$columnName];
                    }
                }
            }

            // entry is relation
            if (! is_numeric($key) && isset($this->relations[$key])) {
                // set value and transform childs to dtos
                $newPath = ($path) ? $path.'.'.$key : $key;
                $dto->{$key} = $this->relations[$key]->toDataTransferObject(
                    $root,
                    $value,
                    $transformations,
                    $newPath
                );
            }
        }

        return $dto;
    }