public function frame($element, $frame)
    {
        if ((false === is_array($frame)) || (1 !== count($frame)) || (false === is_object($frame[0]))) {
            throw new JsonLdException(
                JsonLdException::UNSPECIFIED,
                'The frame is invalid. It must be a single object.',
                $frame
            );
        }

        $frame = $frame[0];

        $options = new JsonObject();
        $options->{'@embed'} = true;
        $options->{'@embedChildren'} = true;   // TODO Change this as soon as the tests haven been updated

        foreach (self::$framingKeywords as $keyword) {
            if (property_exists($frame, $keyword)) {
                $options->{$keyword} = $frame->{$keyword};
                unset($frame->{$keyword});
            } elseif (false === property_exists($options, $keyword)) {
                $options->{$keyword} = false;
            }
        }

        $procOptions = new JsonObject();
        $procOptions->base = (string) $this->baseIri;  // TODO Check which base IRI to use
        $procOptions->compactArrays = $this->compactArrays;
        $procOptions->optimize = $this->optimize;
        $procOptions->useNativeTypes = $this->useNativeTypes;
        $procOptions->useRdfType = $this->useRdfType;
        $procOptions->produceGeneralizedRdf = $this->generalizedRdf;
        $procOptions->documentFactory = $this->documentFactory;
        $procOptions->documentLoader = $this->documentLoader;

        $processor = new Processor($procOptions);

        $graph = JsonLD::MERGED_GRAPH;
        if (property_exists($frame, '@graph')) {
            $graph = JsonLD::DEFAULT_GRAPH;
        }

        $nodeMap = new JsonObject();
        $nodeMap->{'-' . $graph} = new JsonObject();
        $processor->generateNodeMap($nodeMap, $element, $graph);

        // Sort the node map to ensure a deterministic output
        // TODO Move this to a separate function as basically the same is done in flatten()?
        $nodeMap = (array) $nodeMap;
        foreach ($nodeMap as &$nodes) {
            $nodes = (array) $nodes;
            ksort($nodes);
            $nodes = (object) $nodes;
        }
        $nodeMap = (object) $nodeMap;

        unset($processor);

        $result = array();

        foreach ($nodeMap->{'-' . $graph} as $node) {
            $this->nodeMatchesFrame($node, $frame, $options, $nodeMap, $graph, $result);
        }

        return $result;
    }