protected function getNodeID( $doc )
    {
        $docPathStrings = $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'path_string' )];
        $docVisibilities = $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'is_invisible' )];
        if ( count( $docPathStrings ) > 1 )
        {
            // reordering the path strings and the associated visibilities so
            // that the main node path string and the main node visibility are
            // in the first position.
            $mainNodeIdx = array_search(
                $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'main_path_string' )],
                $docPathStrings
            );
            if ( $mainNodeIdx != 0 )
            {
                array_unshift( $docVisibilities, $docVisibilities[$mainNodeIdx] );
                array_unshift( $docPathStrings, $docPathStrings[$mainNodeIdx] );
                // adding +1 to indexing because of array_unshift
                unset( $docVisibilities[$mainNodeIdx + 1], $docPathStrings[$mainNodeIdx + 1] );
            }
        }
        $locationFilter = isset( $this->postSearchProcessingData['subtree_array'] ) ? $this->postSearchProcessingData['subtree_array'] : array();
        $subtreeLimitations = isset( $this->postSearchProcessingData['subtree_limitations'] ) ? $this->postSearchProcessingData['subtree_limitations'] : array();
        $validSubtreeArray = $this->getValidPathStringsByLimitation(
            $docPathStrings,
            $locationFilter
        );
        $validSubtreeLimitations = $this->getValidPathStringsByLimitation(
            $docPathStrings,
            $subtreeLimitations
        );
        $ignoreVisibility = eZContentObjectTreeNode::showInvisibleNodes();
        if ( isset( $this->postSearchProcessingData['ignore_visibility'] ) )
        {
            $ignoreVisibility = $this->postSearchProcessingData['ignore_visibility'];
        }


        // Intersect between $validSubtreeArray (search location filter) and $validSubtreeLimitations (user policy limitations)
        // indicates valid locations for $doc in current search query
        // If this intersect is not empty, we take the first node id that
        // matches the visibility requirement
        $validSubtrees = array_flip(
            array_intersect( $validSubtreeArray, $validSubtreeLimitations )
        );
        if ( !empty( $validSubtrees ) )
        {
            foreach ( $docPathStrings as $k => $path )
            {
                if ( isset( $validSubtrees[$path] ) )
                {
                    if ( $ignoreVisibility || !$docVisibilities[$k] )
                    {
                        $nodeArray = explode( '/', rtrim( $path, '/' ) );
                        return (int)array_pop( $nodeArray );
                    }
                }
            }
            // Could not find a visible location for content that current user has read access on.
            return null;
        }
        else
        {
            $contentId = $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'id' )];
            $content = eZContentObject::fetch( $contentId );
            if ( $content instanceof eZContentObject && !$content->canRead() )
            {
                eZDebug::writeError(
                    "Could not find valid/granted locations for content #$contentId. Broken sync between eZPublish and Solr ?\n\n" .
                    "Location filter : " . print_r( $locationFilter, true ) .
                    "Subtree limitations for user : " . print_r( $subtreeLimitations, true ),
                    __METHOD__
                );
            }
            foreach ( $docPathStrings as $k => $path )
            {
                if ( $ignoreVisibility || !$docVisibilities[$k] )
                {
                    $nodeArray = explode( '/', rtrim( $path, '/' ) );
                    return (int)array_pop( $nodeArray );
                }
            }
        }

        return (int)$doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'main_node_id' )];
    }