}
	private Sequence selectByPosition(Sequence outerSequence, Sequence contextSequence, int mode, Expression inner) throws XPathException {		if(outerSequence != null && !outerSequence.isEmpty() && 				Type.subTypeOf(contextSequence.getItemType(), Type.NODE)) {			Sequence result = new ExtArrayNodeSet(100);			NodeSet contextSet = contextSequence.toNodeSet();            switch(mode) {            case Constants.CHILD_AXIS:            case Constants.ATTRIBUTE_AXIS:            case Constants.DESCENDANT_AXIS:            case Constants.DESCENDANT_SELF_AXIS:            case Constants.DESCENDANT_ATTRIBUTE_AXIS:             {        		        		NodeSet outerNodeSet;        		        		//Ugly and costly processing of VirtualNodeSEts        		//TODO : CORRECT THIS !!!        		        		if (outerSequence instanceof VirtualNodeSet) {        			outerNodeSet = new ArraySet(outerSequence.getLength());        			for (int i = 0 ; i < outerSequence.getLength() ; i++) {        				outerNodeSet.add(outerSequence.itemAt(i));        			}        		} else outerNodeSet = outerSequence.toNodeSet();       		        		        		//Comment the line below if you have uncommented the lines above :-)            	            	//TODO: in some cases, especially with in-memory nodes,             	//outerSequence.toNodeSet() will generate a document            	//which will be different from the one(s) in contextSet            	//ancestors will thus be empty :-(            	if (outerSequence instanceof VirtualNodeSet)            		((VirtualNodeSet)outerSequence).realize(); 				Sequence ancestors = contextSet.selectAncestorDescendant(outerNodeSet,						NodeSet.ANCESTOR, true, getExpressionId()); 				if (contextSet.getDocumentSet().intersection(outerNodeSet.getDocumentSet()).getLength() == 0)					LOG.info("contextSet and outerNodeSet don't share any document");				ArraySet temp = new ArraySet(100);				for(SequenceIterator i = ancestors.iterate(); i.hasNext(); ) {									    NodeProxy p = (NodeProxy)i.nextItem();				    ContextItem contextNode = p.getContext();				    temp.reset();				    while (contextNode != null) {				    	if (contextNode.getContextId() == getExpressionId())				    		temp.add(contextNode.getNode());				    	contextNode = contextNode.getNextDirect();				    }                    //TODO : understand why we sort here...				    temp.sortInDocumentOrder();				                        Sequence innerSeq = inner.eval(contextSequence);                    				    for(SequenceIterator j = innerSeq.iterate(); j.hasNext(); ) {				      				        NumericValue v = (NumericValue)j.nextItem().convertTo(Type.NUMBER);				        //... whereas we don't want a sorted array here                        //TODO : rename this method as getInDocumentOrder ? -pb				        p = temp.getUnsorted(v.getInt() - 1);				        if (p != null)				        	result.add(p);                        //TODO : does null make sense here ?				    }				}                break;            }            default:				for (SequenceIterator i = outerSequence.iterate(); i.hasNext(); ) {				   				    NodeProxy p = (NodeProxy)i.nextItem();				    Sequence temp;                    boolean reverseAxis = true;                    switch(mode) {                    case Constants.ANCESTOR_AXIS:                                                    temp = contextSet.selectAncestors(p, false, Expression.IGNORE_CONTEXT);                        break;                    case Constants.ANCESTOR_SELF_AXIS:                       temp = contextSet.selectAncestors(p, true, Expression.IGNORE_CONTEXT);                        break;                    case Constants.PARENT_AXIS:                        //TODO : understand why the contextSet is not involved here                        //NodeProxy.getParent returns a *theoretical* parent                         //which is *not* guaranteed to be in the context set !                        temp = p.getParents(Expression.NO_CONTEXT_ID);                        break;                                                case Constants.PRECEDING_AXIS:                        temp = contextSet.selectPreceding(p);                        break;                    case Constants.PRECEDING_SIBLING_AXIS:                        temp = contextSet.selectPrecedingSiblings(p, Expression.IGNORE_CONTEXT);                        break;                    case Constants.FOLLOWING_SIBLING_AXIS:                        temp = contextSet.selectFollowingSiblings(p, Expression.IGNORE_CONTEXT);                        reverseAxis = false;                        break;                        case Constants.FOLLOWING_AXIS:                        temp = contextSet.selectFollowing(p);                        reverseAxis = false;                        break;                    case Constants.SELF_AXIS:                        temp = p;                        reverseAxis = false;                        break;                                                default:                                                    //temp = contextSet.selectAncestorDescendant(p, NodeSet.DESCENDANT, false, false);                        //break;                        throw new IllegalArgumentException("Tested unknown axis");                    }                    if (!temp.isEmpty()) {                        //TODO : build a value sequence *one* time ? -pb                        Sequence innerSeq = inner.eval(contextSequence);                                                for(SequenceIterator j = innerSeq.iterate(); j.hasNext(); ) {                                                NumericValue v = (NumericValue)j.nextItem().convertTo(Type.NUMBER);                                                         int pos = (reverseAxis ? temp.getLength() - v.getInt() : v.getInt() - 1);                            //Other positions are ignored                            if (pos >= 0 && pos < temp.getLength()) {                                NodeProxy t = (NodeProxy) temp.itemAt(pos);                                // for the current context: filter out those context items                                // not selected by the positional predicate                                ContextItem ctx = t.getContext();                                t.clearContext(Expression.IGNORE_CONTEXT);                                while (ctx != null) {                                    if (ctx.getContextId() == outerContextId) {                                        if (ctx.getNode().getGID() == p.getGID())                                            t.addContextNode(outerContextId, ctx.getNode());                                    } else                                        t.addContextNode(ctx.getContextId(), ctx.getNode());                                    ctx = ctx.getNextDirect();                                }                                result.add(t);                            }                                               }                    }    			}			}			return result;		} else {             ValueSequence result = new ValueSequence();			Sequence innerSeq = inner.eval(contextSequence);						for(SequenceIterator i = innerSeq.iterate(); i.hasNext(); ) {				NumericValue v = (NumericValue)i.nextItem().convertTo(Type.NUMBER);				int pos = v.getInt() - 1;                //Other positions are ignored    				if(pos >= 0 && pos < contextSequence.getLength())					result.add(contextSequence.itemAt(pos));                            			}			return result;		}	}