@Override
    public boolean matches(TreeMatcher matcher, ASTNode n)
    {
        if ( thisNodeMatcher == null ) {
            throw new IllegalStateException("At least the INodeMatcher for the main node needs to be set");
        }
        
        matchedLeftChild = matchedRightChild = matchedParent = null;
        
        ASTNode matchedNode = unwrap(n,unwrapParent); 
        if ( requiresNodeToHaveParent && ! matchedNode.hasParent() ) {
            return false;
        }
        boolean matches = thisNodeMatcher.matches( matcher, matchedNode );
        if ( matches ) {
            matchedParent = n;
        }
        
        if ( matches ) {
            matches &= hasMatchingChildren( matchedNode );
        }
        
        if ( matches && extraMatcher != null ) {
            matches &= extraMatcher.matches( this , matchedParent );
            if ( ! matches ) {
                matchedParent = null;
            }
        }
        return matches;
    }