You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sa...@apache.org on 2002/10/08 23:44:15 UTC

cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/util IntegerArray.java

santiagopg    2002/10/08 14:44:15

  Modified:    java/src/org/apache/xalan/xsltc DOM.java
               java/src/org/apache/xalan/xsltc/compiler ApplyTemplates.java
                        Constants.java ForEach.java LastCall.java
                        Parser.java PositionCall.java Step.java
               java/src/org/apache/xalan/xsltc/dom AbsoluteIterator.java
                        CurrentNodeListIterator.java DOMAdapter.java
                        DOMImpl.java DupFilterIterator.java
                        FilterIterator.java FilteredStepIterator.java
                        KeyIndex.java MatchingIterator.java MultiDOM.java
                        NodeIteratorBase.java NthIterator.java
                        StepIterator.java
               java/src/org/apache/xalan/xsltc/util IntegerArray.java
  Added:       java/src/org/apache/xalan/xsltc/dom
                        ForwardPositionIterator.java
  Removed:     java/src/org/apache/xalan/xsltc/dom ReverseIterator.java
  Log:
  (1) Eliminated the need for a ReverseIterator.
  (2) Added a ForwardPositionIterator as a temporary solution for some
  cases.
  (3) Added several javadoc-type comments.
  (4) Fixed a number of cloneIterator() implementations that were broken.
  
  Revision  Changes    Path
  1.11      +1 -3      xml-xalan/java/src/org/apache/xalan/xsltc/DOM.java
  
  Index: DOM.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/DOM.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- DOM.java	24 Apr 2002 17:03:14 -0000	1.10
  +++ DOM.java	8 Oct 2002 21:44:13 -0000	1.11
  @@ -126,8 +126,6 @@
       public String getLanguage(int node);
       public int getSize();
       public String getDocumentURI(int node);
  -    public int getTypedPosition(int type, int node);
  -    public int getTypedLast(int type, int node);
       public void setFilter(StripFilter filter);
       public void setupMapping(String[] names, String[] namespaces);
       public boolean isElement(final int node);
  
  
  
  1.15      +7 -1      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java
  
  Index: ApplyTemplates.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- ApplyTemplates.java	10 May 2002 15:40:02 -0000	1.14
  +++ ApplyTemplates.java	8 Oct 2002 21:44:13 -0000	1.15
  @@ -103,6 +103,12 @@
   	
   	if (select.length() > 0) {
   	    _select = parser.parseExpression(this, "select", null);
  +
  +	    // Wrap _select in a ForwardPositionExpr
  +	    final Expression fpe = new ForwardPositionExpr(_select);
  +	    _select.setParent(fpe);
  +	    fpe.setParser(_select.getParser());
  +	    _select = fpe;
   	}
   	
   	if (mode.length() > 0) {
  
  
  
  1.28      +3 -3      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java
  
  Index: Constants.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- Constants.java	16 Sep 2002 19:33:18 -0000	1.27
  +++ Constants.java	8 Oct 2002 21:44:13 -0000	1.28
  @@ -155,8 +155,8 @@
   	= "org.apache.xalan.xsltc.dom.SortingIterator";
       public static final String SORT_ITERATOR_SIG     
   	= "Lorg.apache.xalan.xsltc.dom.SortingIterator;";
  -    public static final String REVERSE_ITERATOR      
  -	= "org.apache.xalan.xsltc.dom.ReverseIterator";
  +    public static final String FORWARD_POSITION_ITERATOR      
  +	= "org.apache.xalan.xsltc.dom.ForwardPositionIterator";
       public static final String NODE_SORT_RECORD 
   	= "org.apache.xalan.xsltc.dom.NodeSortRecord";
       public static final String NODE_SORT_FACTORY
  
  
  
  1.13      +10 -3     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ForEach.java
  
  Index: ForEach.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ForEach.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- ForEach.java	1 Feb 2002 20:07:08 -0000	1.12
  +++ ForEach.java	8 Oct 2002 21:44:13 -0000	1.13
  @@ -97,8 +97,14 @@
           // make sure required attribute(s) have been set
           if (_select.isDummy()) {
   	    reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "select");
  -	    return;
           }
  +	else {
  +	    // Wrap _select in a ForwardPositionExpr
  +	    final Expression fpe = new ForwardPositionExpr(_select);
  +	    _select.setParent(fpe);
  +	    fpe.setParser(_select.getParser());
  +	    _select = fpe;
  +	}
       }
   	
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  @@ -161,7 +167,8 @@
   	    else {
   		_select.translate(classGen, methodGen);
   	    }
  -	    if (!(_type instanceof ReferenceType)) {
  +
  +	    if (_type instanceof ReferenceType == false) {
   		_select.startResetIterator(classGen, methodGen);
   	    }
   	}
  
  
  
  1.8       +8 -66     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LastCall.java
  
  Index: LastCall.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LastCall.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- LastCall.java	1 Feb 2002 20:07:08 -0000	1.7
  +++ LastCall.java	8 Oct 2002 21:44:13 -0000	1.8
  @@ -71,17 +71,10 @@
   
   final class LastCall extends FunctionCall {
   
  -    private int _type = -1;
  -
       public LastCall(QName fname) {
   	super(fname);
       }
   
  -    public LastCall(QName fname, int type) {
  -	this(fname);
  -	_type = type;
  -    }
  -
       public boolean hasPositionCall() {
   	return true;
       }
  @@ -91,72 +84,21 @@
       }
   
       public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  -
   	final InstructionList il = methodGen.getInstructionList();
  -	final ConstantPoolGen cpg = classGen.getConstantPool();
  -
  -	boolean lastChild = false;
  -
  -	// If we're a part of an pattern's predicate we want to know what
  -	// type of node we want to be looking for (not just any).
  -	if (getParent() instanceof Expression) {
  -	    if (getParent().getParent() instanceof Predicate) {
  -		Predicate pred = (Predicate)getParent().getParent();
  -		_type = pred.getPosType();
  -		if ((_type==DOM.ELEMENT) || (_type==DOM.ATTRIBUTE)) _type = -1;
  -	    }
  -	}
  -
  -	// If we're a part of a step-type expression we want the last of the
  -	// current node's children and not the last in the current iterator.
  -	if (getParent() instanceof Predicate) {
  -	    _type = ((Predicate)getParent()).getPosType();
  -	    if ((_type==DOM.ELEMENT) || (_type==DOM.ATTRIBUTE)) _type = -1;
  -	    if (getParent().getParent() instanceof Step) {
  -		lastChild = true;
  -	    }
  -	}
   
   	if (methodGen instanceof CompareGenerator) {
   	    il.append(((CompareGenerator)methodGen).loadLastNode());
   	}
  -	else if (classGen.isExternal()) {
  +	else if (methodGen instanceof TestGenerator) {
   	    il.append(new ILOAD(LAST_INDEX));
   	}
  -	else if (_type == -1) {
  -	    final int last = cpg.addInterfaceMethodref(NODE_ITERATOR,
  -						       "getLast", 
  -						       "()I");
  -	    final int git = cpg.addInterfaceMethodref(DOM_INTF,
  -						      "getTypedAxisIterator", 
  -						      "(II)"+NODE_ITERATOR_SIG);
  -	    final int start = cpg.addInterfaceMethodref(NODE_ITERATOR,
  -							"setStartNode", 
  -							"(I)"+
  -							NODE_ITERATOR_SIG);
  -	    if (lastChild) {
  -		il.append(methodGen.loadDOM());
  -		il.append(new PUSH(cpg, Axis.CHILD));
  -		il.append(new PUSH(cpg, DOM.ELEMENT));
  -		il.append(new INVOKEINTERFACE(git, 3));
  -		il.append(methodGen.loadCurrentNode());
  -		il.append(new INVOKEINTERFACE(start, 2));
  -	    }
  -	    else {
  -		il.append(methodGen.loadIterator());
  -	    }
  -	    il.append(new INVOKEINTERFACE(last, 1));
  -	}
   	else {
  -	    // public int getTypedLast(int type, int node) {
  -	    final int last = cpg.addInterfaceMethodref(DOM_INTF,
  -						       "getTypedLast",
  -						       "(II)I");
  -	    il.append(methodGen.loadDOM());
  -	    il.append(new PUSH(cpg, _type));
  -	    il.append(methodGen.loadContextNode());
  -	    il.append(new INVOKEINTERFACE(last, 3));
  -
  +	    final ConstantPoolGen cpg = classGen.getConstantPool();
  +	    final int getLast = cpg.addInterfaceMethodref(NODE_ITERATOR,
  +							  "getLast", 
  +							  "()I");
  +	    il.append(methodGen.loadIterator());
  +	    il.append(new INVOKEINTERFACE(getLast, 1));
   	}
       }
   }
  
  
  
  1.53      +2 -1      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Parser.java
  
  Index: Parser.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Parser.java,v
  retrieving revision 1.52
  retrieving revision 1.53
  diff -u -r1.52 -r1.53
  --- Parser.java	16 Sep 2002 19:38:17 -0000	1.52
  +++ Parser.java	8 Oct 2002 21:44:13 -0000	1.53
  @@ -1103,6 +1103,7 @@
   		    node.setParser(this);
   		    node.setParent(parent);
   		    node.setLineNumber(line);
  +// System.out.println("e = " + text + " " + node);
   		    return node;
   		}
   	    } 
  
  
  
  1.9       +2 -40     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/PositionCall.java
  
  Index: PositionCall.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/PositionCall.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- PositionCall.java	1 Feb 2002 20:07:08 -0000	1.8
  +++ PositionCall.java	8 Oct 2002 21:44:13 -0000	1.9
  @@ -71,68 +71,30 @@
   
   final class PositionCall extends FunctionCall {
   
  -    private int _type = -1;
  -
       public PositionCall(QName fname) {
   	super(fname);
       }
   
  -    public PositionCall(QName fname, int type) {
  -	this(fname);
  -	_type = type;
  -    }
  -
       public boolean hasPositionCall() {
   	return true;
       }
   
       public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  -
   	final InstructionList il = methodGen.getInstructionList();
   
  -	SyntaxTreeNode parent = getParent();
  -	SyntaxTreeNode granny = parent.getParent();
  -
  -	// If we're a part of an expression's predicate we want to know what
  -	// type of node we want to be looking for
  -	if ((parent instanceof Expression) && (granny instanceof Predicate)) {
  -	    _type = ((Predicate)granny).getPosType();
  -	}
  -	else {
  -	    while ((granny != null) && !(granny instanceof StepPattern)) {
  -		parent = granny;
  -		granny = granny.getParent();
  -	    }
  -	    if ((parent instanceof Predicate) &&
  -		(granny instanceof StepPattern)){
  -		_type = ((StepPattern)granny).getNodeType();
  -	    }
  -	}
  -
   	if (methodGen instanceof CompareGenerator) {
   	    il.append(((CompareGenerator)methodGen).loadCurrentNode());
   	}
   	else if (methodGen instanceof TestGenerator) {
   	    il.append(new ILOAD(POSITION_INDEX));
   	}
  -	else if (_type == -1) {
  +	else {
   	    final ConstantPoolGen cpg = classGen.getConstantPool();
   	    final int getPosition = cpg.addInterfaceMethodref(NODE_ITERATOR,
   							      "getPosition", 
   							      "()I");
   	    il.append(methodGen.loadIterator());
   	    il.append(new INVOKEINTERFACE(getPosition, 1));
  -	}
  -	else {
  -	    final ConstantPoolGen cpg = classGen.getConstantPool();
  -	    // public int getTypedPosition(int type, int node)
  -	    final int pos = cpg.addInterfaceMethodref(DOM_INTF,
  -						      "getTypedPosition",
  -						      "(II)I");
  -	    il.append(methodGen.loadDOM());
  -	    il.append(new PUSH(cpg, _type));
  -	    il.append(methodGen.loadContextNode());
  -	    il.append(new INVOKEINTERFACE(pos, 3));
   	}
       }
   }
  
  
  
  1.38      +5 -70     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Step.java
  
  Index: Step.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Step.java,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -u -r1.37 -r1.38
  --- Step.java	27 Jun 2002 14:56:29 -0000	1.37
  +++ Step.java	8 Oct 2002 21:44:13 -0000	1.38
  @@ -149,10 +149,12 @@
        * Returns the vector containing all predicates for this step.
        */
       public void addPredicates(Vector predicates) {
  -	if (_predicates == null)
  +	if (_predicates == null) {
   	    _predicates = predicates;
  -	else
  +	}
  +	else {
   	    _predicates.addAll(predicates);
  +	}
       }
   
       /**
  @@ -235,41 +237,6 @@
       }
   
       /**
  -     * This method is used to determine whether the node-set produced by
  -     * this step must be reversed before returned to the parent element.
  -     * <xsl:apply-templates> should always return nodes in document order,
  -     * while others, such as <xsl:value-of> and <xsl:for-each> should return
  -     * nodes in the order of the axis in use.
  -     */
  -    private boolean reverseNodeSet() {
  -	// Check if axis returned nodes in reverse document order
  -	if ((_axis == Axis.ANCESTOR)  || (_axis == Axis.ANCESTORORSELF) ||
  -	    (_axis == Axis.PRECEDING) || (_axis == Axis.PRECEDINGSIBLING)) {
  -
  -	    // Do not reverse nodes if we had predicates
  -	    // if (_hadPredicates) return false;
  -	    
  -	    // Check if this step occured under an <xsl:apply-templates> element
  -	    SyntaxTreeNode parent = this;
  -	    do {
  -		// Get the next ancestor element and check its type
  -		parent = parent.getParent();
  -
  -		// Order node set if descendant of these elements:
  -		if (parent instanceof ApplyImports) return true;
  -		if (parent instanceof ApplyTemplates) return true;
  -		if (parent instanceof ForEach) return true;
  -		if (parent instanceof FilterParentPath) return true;
  -		if (parent instanceof FilterExpr) return true;
  -		if (parent instanceof WithParam) return true;
  -		if (parent instanceof ValueOf) return true;
  -
  -	    } while (parent != null && parent instanceof Instruction == false);
  -	}
  -	return false;
  -    }
  -
  -    /**
        * Translate a step by pushing the appropriate iterator onto the stack.
        * The abbreviated steps '.' and '@attr' do not create new iterators
        * if they are not part of a LocationPath and have no filters.
  @@ -282,11 +249,6 @@
   
   	if (hasPredicates()) {
   	    translatePredicates(classGen, methodGen);
  -
  -	    // If needed, create a reverse iterator after compiling preds
  -	    if (_predicates.size() == 0) {
  -		orderIterator(classGen, methodGen);
  -	    }
   	}
   	else {
   	    // If it is an attribute but not '@*' or '@attr' with a parent
  @@ -383,11 +345,6 @@
   
   		break;
   	    }
  -
  -	    // If needed, create a reverse iterator
  -	    if (!_hadPredicates) {
  -		orderIterator(classGen, methodGen);
  -	    }
   	}
       }
   
  @@ -493,28 +450,6 @@
   	    }
   	}
       }
  -
  -
  -    /**
  -     * This method tests if this step needs to have its axis reversed,
  -     * and wraps its iterator inside a ReverseIterator to return the node-set
  -     * in document order.
  -     */
  -    public void orderIterator(ClassGenerator classGen,
  -			      MethodGenerator methodGen) {
  -	// First test if nodes are in reverse document order
  -	if (!reverseNodeSet()) return;
  -
  -	final ConstantPoolGen cpg = classGen.getConstantPool();
  -	final InstructionList il = methodGen.getInstructionList();
  -	final int init = cpg.addMethodref(REVERSE_ITERATOR, "<init>",
  -					  "("+NODE_ITERATOR_SIG+")V");
  -	il.append(new NEW(cpg.addClass(REVERSE_ITERATOR)));
  -	il.append(DUP_X1);
  -	il.append(SWAP);
  -	il.append(new INVOKESPECIAL(init));
  -    }
  -
   
       /**
        * Returns a string representation of this step.
  
  
  
  1.9       +41 -17    xml-xalan/java/src/org/apache/xalan/xsltc/dom/AbsoluteIterator.java
  
  Index: AbsoluteIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/AbsoluteIterator.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- AbsoluteIterator.java	15 Sep 2002 14:26:36 -0000	1.8
  +++ AbsoluteIterator.java	8 Oct 2002 21:44:14 -0000	1.9
  @@ -67,43 +67,67 @@
   import org.apache.xalan.xsltc.NodeIterator;
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
   
  +/**
  + * Absolute iterators ignore the node that is passed to setStartNode(). 
  + * Instead, they always start from the root node. The node passed to 
  + * setStartNode() is not totally useless, though. It is needed to obtain the 
  + * DOM mask, i.e. the index into the MultiDOM table that corresponds to the 
  + * DOM "owning" the node. 
  + * 
  + * The DOM mask is cached, so successive calls to setStartNode() passing 
  + * nodes from other DOMs will have no effect (i.e. this iterator cannot 
  + * migrate between DOMs).
  + */
   public final class AbsoluteIterator extends NodeIteratorBase {
  +
  +    /**
  +     * Initial value for DOM masks.
  +     */
  +    private static final int NO_MASK = -1;
  +
  +    /**
  +     * Source for this iterator.
  +     */
       private NodeIterator _source;
  +
  +    /**
  +     * DOM mask cached after first call to setStartNode().
  +     */
  +    private int _mask = NO_MASK;
   	
       public AbsoluteIterator(NodeIterator source) {
   	_source = source;
  -    }
  -
  -    public int next() {
  -	return returnNode(_source.next());
  +// System.out.println("AI source = " + source + " this = " + this);
       }
   
       public void setRestartable(boolean isRestartable) {
   	_isRestartable = isRestartable;
   	_source.setRestartable(isRestartable);
       }
  -	
  -    int _mask = -1;
   
       public NodeIterator setStartNode(int node) {
  -	if (_mask == -1) {
  -            _mask = node & 0xFF000000;
  -        }
  -	_startNode = _mask | DOM.ROOTNODE;
   	if (_isRestartable) {
  -	    resetPosition();
  +	    if (_mask == NO_MASK) {
  +		_mask = node & 0xFF000000;
  +	    }
  +	    _startNode = _mask | DOM.ROOTNODE;
   	    _source.setStartNode(_startNode);
  -	    return this;
  +	    resetPosition();
   	}
  -	return reset();
  +	return this;
  +    }
  +
  +    public int next() {
  +	return returnNode(_source.next());
       }
   
       public NodeIterator cloneIterator() {
   	try {
  -	    final AbsoluteIterator clone = (AbsoluteIterator)super.clone();
  -	    clone.setRestartable(false);
  -	    clone._source = _source.cloneIterator();
  -	    return clone.reset();
  +	    final AbsoluteIterator clone = (AbsoluteIterator) super.clone();
  +	    clone._source = _source.cloneIterator();	// resets source
  +	    clone.resetPosition();
  +	    clone._isRestartable = false;
  +	    return clone;
   	}
   	catch (CloneNotSupportedException e) {
   	    BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
  
  
  
  1.9       +64 -22    xml-xalan/java/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java
  
  Index: CurrentNodeListIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- CurrentNodeListIterator.java	13 Jun 2002 12:26:16 -0000	1.8
  +++ CurrentNodeListIterator.java	8 Oct 2002 21:44:14 -0000	1.9
  @@ -69,17 +69,51 @@
   import org.apache.xalan.xsltc.util.IntegerArray;
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
   
  +/**
  + * Iterators of this kind use a CurrentNodeListFilter to filter a subset of 
  + * nodes from a source iterator. For each node from the source, the boolean 
  + * method CurrentNodeListFilter.test() is called. 
  + *
  + * All nodes from the source are read into an array upon calling setStartNode() 
  + * (this is needed to determine the value of last, a parameter to 
  + * CurrentNodeListFilter.test()). The method getLast() returns the last element 
  + * after applying the filter.
  + */
   public final class CurrentNodeListIterator extends NodeIteratorBase {
   
  +    /**
  +     * A flag indicating if nodes are returned in document order.
  +     */
       private boolean _docOrder;
  +
  +    /**
  +     * The source for this iterator.
  +     */
       private NodeIterator _source;
  +
  +    /**
  +     * A reference to a filter object.
  +     */
       private final CurrentNodeListFilter _filter;
  +
  +    /**
  +     * An integer array to store nodes from source iterator.
  +     */
       private IntegerArray _nodes = new IntegerArray();
   	
  -    private int _current;	// index in _nodes of the next node to try
  -    private int _last = -1;		
  +    /**
  +     * Index in _nodes of the next node to filter.
  +     */
  +    private int _currentIndex;
   	
  +    /**
  +     * The current node in the stylesheet at the time of evaluation.
  +     */
       private final int _currentNode;
  +
  +    /**
  +     * A reference to the translet.
  +     */
       private AbstractTranslet _translet;
   
       public CurrentNodeListIterator(NodeIterator source, 
  @@ -114,9 +148,10 @@
       public NodeIterator cloneIterator() {
   	try {
   	    final CurrentNodeListIterator clone =
  -		(CurrentNodeListIterator)super.clone();
  -	    clone._nodes = (IntegerArray)_nodes.clone();
  -	    clone.setRestartable(false);
  +		(CurrentNodeListIterator) super.clone();
  +	    clone._nodes = (IntegerArray) _nodes.clone();
  +	    clone._source = _source.cloneIterator();
  +	    clone._isRestartable = false;
   	    return clone.reset();
   	}
   	catch (CloneNotSupportedException e) {
  @@ -127,7 +162,7 @@
       }
       
       public NodeIterator reset() {
  -	_current = 0;
  +	_currentIndex = 0;
   	return resetPosition();
       }
   
  @@ -136,10 +171,12 @@
   	final int currentNode = _currentNode;
   	final AbstractTranslet translet = _translet;
   
  -	for (int index = _current; index < last; ) {
  +	for (int index = _currentIndex; index < last; ) {
  +	    final int position = _docOrder ? index + 1 : last - index;
   	    final int node = _nodes.at(index++); 	// note increment
  -	    if (_filter.test(node, index, last, currentNode, translet, this)) {
  -		_current = index;
  +
  +	    if (_filter.test(node, position, last, currentNode, translet, this)) {
  +		_currentIndex = index;
   		return returnNode(node);
   	    }
   	}
  @@ -147,8 +184,6 @@
       }
   
       public NodeIterator setStartNode(int node) {
  -	NodeIterator retval = this;
  -	
   	if (_isRestartable) {
   	    _source.setStartNode(_startNode = node);
   
  @@ -156,12 +191,19 @@
   	    while ((node = _source.next()) != END) {
   		_nodes.add(node);
   	    }
  -	    _current = 0;
  -	    retval = resetPosition();
  +	    _currentIndex = 0;
  +	    resetPosition();
   	}
  -	return retval;
  +	return this;
       }
   	
  +    public int getPosition() {
  +	if (_last == -1) {
  +	    _last = computePositionOfLast();
  +	}
  +	return _docOrder ? _position : _last - _position + 1;
  +    }
  +
       public int getLast() {
   	if (_last == -1) {
   	    _last = computePositionOfLast();
  @@ -170,13 +212,11 @@
       }
   
       public void setMark() {
  -	_source.setMark();
  -	_markedNode = _current;
  +	_markedNode = _currentIndex;
       }
   
       public void gotoMark() {
  -	_source.gotoMark();
  -	_current = _markedNode;
  +	_currentIndex = _markedNode;
       }
   
       private int computePositionOfLast() {
  @@ -184,10 +224,12 @@
           final int currNode = _currentNode;
   	final AbstractTranslet translet = _translet;
   
  -	int lastPosition = 0;
  -	for (int index = _current; index < last; ) {
  +	int lastPosition = _position;
  +	for (int index = _currentIndex; index < last; ) {
  +	    final int position = _docOrder ? index + 1 : last - index;
               int nodeIndex = _nodes.at(index++); 	// note increment
  -            if (_filter.test(nodeIndex, index, last, currNode, translet, this)) {
  +
  +            if (_filter.test(nodeIndex, position, last, currNode, translet, this)) {
                   lastPosition++;
               }
           }
  
  
  
  1.15      +1 -9      xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMAdapter.java
  
  Index: DOMAdapter.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMAdapter.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- DOMAdapter.java	21 Sep 2002 17:53:23 -0000	1.14
  +++ DOMAdapter.java	8 Oct 2002 21:44:14 -0000	1.15
  @@ -237,14 +237,6 @@
   	return _domImpl.getParent(node);
       }
   
  -    public int getTypedPosition(int type, int node) {
  -	return _domImpl.getTypedPosition(getReverse()[type], node);
  -    }
  -
  -    public int getTypedLast(int type, int node) {
  -	return _domImpl.getTypedLast(getReverse()[type], node);
  -    }
  -
       public int getAttributeNode(final int type, final int element) {
   	return _domImpl.getAttributeNode(getReverse()[type], element);
       }
  
  
  
  1.86      +116 -173  xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMImpl.java
  
  Index: DOMImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMImpl.java,v
  retrieving revision 1.85
  retrieving revision 1.86
  diff -u -r1.85 -r1.86
  --- DOMImpl.java	27 Sep 2002 18:59:33 -0000	1.85
  +++ DOMImpl.java	8 Oct 2002 21:44:14 -0000	1.86
  @@ -1151,26 +1151,20 @@
        * Iterator that returns preceding siblings of a given node
        */
       private class PrecedingSiblingIterator extends NodeIteratorBase {
  -
  + 
   	private int _node;
  -	private int _mom;
  -         
  +	private int _sibling;
  +
   	public boolean isReverse() {
   	    return true;
   	}
            
   	public NodeIterator setStartNode(int node) {
   	    if (_isRestartable) {
  -		if (node >= _firstAttributeNode) node = NULL;
  -		int tmp = NULL;
  -		_startNode = node;
  -		_mom = _parent[node];
  -		_node = _offsetOrChild[_mom];
  -		while ((_node != node) && (_node != NULL)) {
  -		    tmp = _node;
  -		    _node = _nextSibling[_node];
  -		}
  -		_node = tmp;
  +		_node = node;
  +		_sibling = _startNode = (node >= _firstAttributeNode) ? 
  +		    NULL : _offsetOrChild[_parent[node]];
  +		_last = -1;
   		return resetPosition();
   	    }
   	    return this;
  @@ -1178,27 +1172,34 @@
   
   	public int next() {
   	    // Return NULL if end already reached
  -	    if (_node == NULL) return NULL;
  -
  -	    int current = _offsetOrChild[_mom];
  +	    if (_sibling == NULL) {
  +		return END;
  +	    }
   
  -	    // Otherwise find the next preceeding sibling
  -	    int last = NULL;
  -	    while ((current != _node) && (current != NULL)) {
  -		last = current;
  -		current = _nextSibling[current];
  +	    if (_sibling == _node) {
  +		return (_node = END);
   	    }
  -	    current = _node;
  -	    _node = last;
  +
  +	    final int current = _sibling;
  +	    _sibling = _nextSibling[current];
   	    return returnNode(current);
   	}
   
  +	public NodeIterator reset() {
  +	    _sibling = _startNode;
  +	    return resetPosition();
  +	}
  +
  +	public int getPosition() {
  +	    return getLast() - _position + 1;
  +	}
  +
   	public void setMark() {
  -	    _markedNode = _node;
  +	    _markedNode = _sibling;
   	}
   
   	public void gotoMark() {
  -	    _node = _markedNode;
  +	    _sibling = _markedNode;
   	}
   
       } // end of PrecedingSiblingIterator
  @@ -1209,7 +1210,8 @@
        * a given node
        */
       private final class TypedPrecedingSiblingIterator
  -	extends PrecedingSiblingIterator {
  +	extends PrecedingSiblingIterator 
  +    {
   	private final int _nodeType;
   
   	public TypedPrecedingSiblingIterator(int type) {
  @@ -1218,9 +1220,10 @@
            
   	public int next() {
   	    int node;
  -	    while ((node = super.next()) != NULL && _type[node] != _nodeType)
  +	    while ((node = super.next()) != NULL && _type[node] != _nodeType) {
   		_position--;
  -	    return(node);
  +	    }
  +	    return node;
   	}
   
       } // end of PrecedingSiblingIterator
  @@ -1233,8 +1236,10 @@
        */
       private class PrecedingIterator extends NodeIteratorBase {
   
  -	private int _node = 0;
  -	private int _mom = 0;
  +	private int _node;
  +	private int _ancestor;
  +	private int _index, _markedIndex;
  +	private IntegerArray _ancestorOrSelf = new IntegerArray();
   
   	public boolean isReverse() {
   	    return true;
  @@ -1243,8 +1248,9 @@
   	public NodeIterator cloneIterator() {
   	    try {
   		final PrecedingIterator clone = 
  -		    (PrecedingIterator)super.clone();
  +		    (PrecedingIterator) super.clone();
   		clone.setRestartable(false);
  +		clone._ancestorOrSelf = (IntegerArray) _ancestorOrSelf.clone();
   		return clone.reset();
   	    }
   	    catch (CloneNotSupportedException e) {
  @@ -1256,37 +1262,60 @@
            
   	public NodeIterator setStartNode(int node) {
   	    if (_isRestartable) {
  -		if (node >= _firstAttributeNode) node = _parent[node];
  -		_node = _startNode = node;
  -		_mom  = _parent[_startNode];
  +		_ancestorOrSelf.clear();
  +
  +		if (node >= _firstAttributeNode) {
  +		    node = _parent[node];
  +		}
  +		do {
  +		    _ancestorOrSelf.add(node);
  +		} while ((node = _parent[node]) > ROOTNODE);
  +
  +		_index = _ancestorOrSelf.cardinality() - 1;
  +		_node = _ancestorOrSelf.at(_index) + 1;
  +		_ancestor = (_index > 0) ? _ancestorOrSelf.at(--_index) 
  +		    : ROOTNODE;
  +
  +		_last = -1;
   		return resetPosition();
   	    }
  +
   	    return this;
   	}
  -                  
  +	    
   	public int next() {
  -	    while (--_node > ROOTNODE) {
  -		if (_node < _mom) _mom = _parent[_mom];
  -		if (_node != _mom) return returnNode(_node);
  +	    while (true) {
  +		if (_node < _ancestor) {
  +		    return returnNode(_node++);
  +		}
  +		if (--_index < 0) break;
  +		_ancestor = _ancestorOrSelf.at(_index);
  +		_node++;	// skip ancestor
   	    }
  -	    return(NULL);
  +	    return END;
  +	}
  +
  +	public int getPosition() {
  +	    return getLast() - _position + 1;
   	}
   
  -	// redefine NodeIteratorBase's reset
   	public NodeIterator reset() {
  -	    _node = _startNode;
  -	    _mom  = _parent[_startNode];
  +	    _index = _ancestorOrSelf.cardinality() - 1;
  +	    _node = _ancestorOrSelf.at(_index) + 1;
  +	    _ancestor = (_index > 0) ? _ancestorOrSelf.at(--_index) : ROOTNODE;
   	    return resetPosition();
   	}
   
   	public void setMark() {
   	    _markedNode = _node;
  +	    _markedIndex = _index;
   	}
   
   	public void gotoMark() {
   	    _node = _markedNode;
  +	    _index = _markedIndex;
  +	    _ancestor = _ancestorOrSelf.at(_markedIndex);
   	}
  -
       } // end of PrecedingIterator
   
   
  @@ -1304,8 +1333,9 @@
            
   	public int next() {
   	    int node;
  -	    while ((node = super.next()) != NULL && _type[node] != _nodeType)
  +	    while ((node = super.next()) != NULL && _type[node] != _nodeType) {
   		_position--; 
  +	    }
   	    return node;
   	}
   
  @@ -1386,26 +1416,13 @@
       private class AncestorIterator extends NodeIteratorBase {
   
   	protected int _index;
  -	protected int _last = -1;
  -
  -	public final boolean isReverse() {
  -	    return true;
  -	}
  -
  -	public int getLast() {
  -	    if (_last > -1) return _last;
  -	    int count = 1;
  -	    int node = _startNode;
  -	    while ((node = _parent[node]) != ROOT) count++;
  -	    _last = count;
  -	    return(count);
  -	}
  +	protected IntegerArray _cache = new IntegerArray();
            
   	public NodeIterator cloneIterator() {
   	    try {
   		final AncestorIterator clone = (AncestorIterator)super.clone();
   		clone.setRestartable(false); // must set to false for any clone
  -		clone._startNode = _startNode;
  +		clone._cache = (IntegerArray) _cache.clone();
   		return clone.reset();
   	    }
   	    catch (CloneNotSupportedException e) {
  @@ -1417,34 +1434,42 @@
                     
   	public NodeIterator setStartNode(int node) {
   	    if (_isRestartable) {
  -		_last = -1;
  +		_cache.clear();
  +
   		if (_includeSelf) {
  -		    _startNode = node;
  -		}
  -		else if (node >= _firstAttributeNode) {
  -		    _startNode = node = _parent[node];
  +		    _cache.add(node);
   		}
  -		else {
  -		    _startNode = _parent[node];
  +		while ((node = _parent[node]) != NULL) {
  +		    _cache.add(node);
   		}
  -		_index = _startNode;
  +
  +		_last = _cache.cardinality();
  +		_startNode = _index = _last - 1;
   		return resetPosition();
   	    }
   	    return this;
   	}
   
  +	public boolean isReverse() {
  +	    return true;
  +	}
  +
  +	public int getLast() {
  +	    return _last;
  +	}
  +
  +	public int getPosition() {
  +	    return _last - _position + 1;	
  +	}
  +
   	public NodeIterator reset() {
   	    _index = _startNode;
   	    return resetPosition();
   	}
                     
   	public int next() {
  -	    if (_index >= 0) {
  -		final int node = _index;
  -		_index = (_index == 0) ? -1 : _parent[_index];
  -		return returnNode(node);
  -	    }
  -	    return(NULL);
  +	    return (_index >= 0) ? 
  +		returnNode(_cache.at(_index--)) : END;
   	}
   
   	public void setMark() {
  @@ -1468,26 +1493,25 @@
   	    _nodeType = type;
   	}
   
  -	public int next() {
  -	    int node;
  -	    while ((node = super.next()) != NULL) {
  -		if (_type[node] == _nodeType) return(node);
  -		_position--;
  -	    }
  -	    return(NULL);
  -	}
  +	public NodeIterator setStartNode(int node) {
  +	    if (_isRestartable) {
  +		_cache.clear();
   
  -	public int getLast() {
  -	    if (_last > -1) return _last;
  -	    int count = 1;
  -	    int node = _startNode;
  -	    do {
  -		if (_type[node] == _nodeType) count++;
  -	    } while ((node = _parent[node]) != ROOT);
  -	    _last = count;
  -	    return(count);
  -	}
  +		if (_includeSelf && _type[node] == _nodeType) {
  +		    _cache.add(node);
  +		}
  +		while ((node = _parent[node]) != NULL) {
  +		    if (_nodeType == _type[node]) {
  +			_cache.add(node);
  +		    }
  +		}
   
  +		_last = _cache.cardinality();
  +		_startNode = _index = _last - 1;
  +		return resetPosition();
  +	    }
  +	    return this;
  +	}
       } // end of TypedAncestorIterator
   
   
  @@ -1895,87 +1919,6 @@
        */
       public int getParent(final int node) {
   	return _parent[node];
  -    }
  -
  -    public int getElementPosition(int node) {
  -	// Initialize with the first sbiling of the current node
  -	int match = 0;
  -	int curr  = _offsetOrChild[_parent[node]];
  -	if (isElement(curr)) match++;
  -
  -	// Then traverse all other siblings up until the current node
  -	while (curr != node) {
  -	    curr = _nextSibling[curr];
  -	    if (isElement(curr)) match++;
  -	}
  -
  -	// And finally return number of matches
  -	return match;         
  -    }
  -
  -    public int getAttributePosition(int attr) {
  -	// Initialize with the first sbiling of the current node
  -	int match = 1;
  -	int curr  = _lengthOrAttr[_parent[attr]];
  -
  -	// Then traverse all other siblings up until the current node
  -	while (curr != attr) {
  -	    curr = _nextSibling[curr];
  -	    match++;
  -	}
  -
  -	// And finally return number of matches
  -	return match;         
  -    }
  -
  -    /**
  -     * Returns a node's position amongst other nodes of the same type
  -     */
  -    public int getTypedPosition(int type, int node) {
  -	// Just return the basic position if no type is specified
  -	switch(type) {
  -	case ELEMENT:
  -	    return getElementPosition(node);
  -	case ATTRIBUTE:
  -	    return getAttributePosition(node);
  -	case -1:
  -	    type = _type[node];
  -	}
  -
  -	// Initialize with the first sbiling of the current node
  -	int match = 0;
  -	int curr  = _offsetOrChild[_parent[node]];
  -	if (_type[curr] == type) match++;
  -
  -	// Then traverse all other siblings up until the current node
  -	while (curr != node) {
  -	    curr = _nextSibling[curr];
  -	    if (_type[curr] == type) match++;
  -	}
  -
  -	// And finally return number of matches
  -	return match;         
  -    }
  -
  -    /**
  -     * Returns an iterator's last node of a given type
  -     */
  -    public int getTypedLast(int type, int node) {
  -	// Just return the basic position if no type is specified
  -	if (type == -1) type = _type[node];
  -
  -	// Initialize with the first sbiling of the current node
  -	int match = 0;
  -	int curr  = _offsetOrChild[_parent[node]];
  -	if (_type[curr] == type) match++;
  -
  -	// Then traverse all other siblings up until the very last one
  -	while (curr != NULL) {
  -	    curr = _nextSibling[curr];
  -	    if (_type[curr] == type) match++;
  -	}
  -
  -	return match;         
       }
   
       /**
  
  
  
  1.9       +79 -86    xml-xalan/java/src/org/apache/xalan/xsltc/dom/DupFilterIterator.java
  
  Index: DupFilterIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DupFilterIterator.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- DupFilterIterator.java	26 Sep 2001 13:26:25 -0000	1.8
  +++ DupFilterIterator.java	8 Oct 2002 21:44:14 -0000	1.9
  @@ -66,128 +66,121 @@
   import org.apache.xalan.xsltc.NodeIterator;
   import org.apache.xalan.xsltc.TransletException;
   
  +import org.apache.xalan.xsltc.util.IntegerArray;
  +import org.apache.xalan.xsltc.runtime.BasisLibrary;
  +
  +/**
  + * Removes duplicates and sorts a source iterator. The nodes from the 
  + * source are collected in an array upon calling setStartNode(). This
  + * array is later sorted and duplicates are ignored in next().
  + */
   public final class DupFilterIterator extends NodeIteratorBase {
   
  -    private final static int INIT_DATA_SIZE = 16;
  +    /**
  +     * Reference to source iterator.
  +     */
  +    private NodeIterator _source;
  +
  +    /**
  +     * Array to cache all nodes from source.
  +     */
  +    private IntegerArray _nodes = new IntegerArray();
   
  -    private final NodeIterator _source; // the source iterator
  -    private int[] _data = null;         // cached nodes from the source
  -    private int _last = 0;              // the number of nodes in this iterator
  +    /**
  +     * Index in _nodes array to current node.
  +     */
       private int _current = 0;
   
       /**
  -     * Creates a new duplicate filter iterator based on an existing iterator.
  -     * This iterator should be used with union expressions and other complex
  -     * iterator combinations (like 'get me the parents of all child node in
  -     * the dom' sort of thing). The iterator is also used to cache node-sets
  -     * returned by id() and key() iterators.
  -     * @param source The iterator this iterator will get its nodes from
  +     * Cardinality of _nodes array.
  +     */
  +    private int _nodesSize = 0; 
  +
  +    /**
  +     * Last value returned by next().
        */
  +    private int _lastNext = END;
  +
       public DupFilterIterator(NodeIterator source) {
  -	// Save a reference to the source iterator
   	_source = source;
  +// System.out.println("DFI source = " + source + " this = " + this);
   
   	// Cache contents of id() or key() index right away. Necessary for
   	// union expressions containing multiple calls to the same index, and
   	// correct as well since start-node is irrelevant for id()/key() exrp.
  -	if (source instanceof KeyIndex) setStartNode(DOM.ROOTNODE);
  -    }
  -
  -    /**
  -     * Returns the next node in this iterator - excludes duplicates.
  -     * @return The next node in this iterator
  -     */
  -    public int next() {
  -	return _current < _last ? _data[_current++] : END;
  +	if (source instanceof KeyIndex) {
  +	    setStartNode(DOM.ROOTNODE);
  +	}
       }
   
  -    /**
  -     * Set the start node for this iterator
  -     * @param node The start node
  -     * @return A reference to this node iterator
  -     */
       public NodeIterator setStartNode(int node) {
  +	if (_isRestartable) {
  +	    // KeyIndex iterators are always relative to the root node, so there
  +	    // is never any point in re-reading the iterator (and we SHOULD NOT).
  +	    if (_source instanceof KeyIndex && _startNode == DOM.ROOTNODE) {
  +		return this;
  +	    }
   
  -	int i, j; // loop variables declared first for speed - don't move!!!
  -
  -	// KeyIndex iterators are always relative to the root node, so there
  -	// is never any point in re-reading the iterator (and we SHOULD NOT).
  -	if ((_source instanceof KeyIndex) && (_data != null)) return this;
  -
  -	// If the _data array is populated, and the current start node is
  -	// equal to the new start node, we know we already have what we need.
  -	if ((_data == null) || (node != _startNode)) {
  -
  -	    _startNode = node;
  -	    _last = 0;
  -	    _source.setStartNode(node);
  -	    _data = new int[INIT_DATA_SIZE];
  -
  -	    // Gather all nodes from the source iterator, eliminate dups
  -	    while ((node = _source.next()) != END) {
  -		if (_last == _data.length) {
  -		    int[] newArray = new int[_data.length * 2];
  -		    System.arraycopy(_data, 0, newArray, 0, _last);
  -		    _data = newArray;
  -		}
  +	    if (node != _startNode) {
  +		_source.setStartNode(_startNode = node);
   
  -		// Go through all nodes in turn
  -		for (i=0; i<_last; i++) {
  -		    // Is this a duplicate of the new node
  -		    if (_data[i] == node) {
  -			break;
  -		    }
  -		    // Should the new node be inserted at this position?
  -		    else if (_data[i] > node) {
  -			for (j = _last++; j>i; j--)
  -			    _data[j] = _data[j-1];
  -			_data[i] = node;
  -			break;
  -		    }
  +		_nodes.clear();
  +		while ((node = _source.next()) != END) {
  +		    _nodes.add(node);
   		}
  -		if (i == _last) _data[_last++] = node;
  +		_nodes.sort();
  +		_nodesSize = _nodes.cardinality();
  +		_current = 0;
  +		_lastNext = END;
  +		resetPosition();
   	    }
   	}
  -
  -	_current = 0;  // set to beginning 
   	return this;
       }
   
  -    /**
  -     * Returns the current position of the iterator. The position is within the
  -     * node set covered by this iterator, not within the DOM.
  -     */
  -    public int getPosition() {
  -	return (_current);
  +
  +    public int next() {
  +	while (_current < _nodesSize) {
  +	    final int next = _nodes.at(_current++);
  +	    if (next != _lastNext) {
  +		return returnNode(_lastNext = next);
  +	    }
  +	}
  +	return END;
       }
   
  -    /**
  -     * Returns the position of the last node in this iterator. The integer
  -     * returned is equivalent to the number of nodes in this iterator.
  -     */
  -    public int getLast() {
  -	return _last;
  +    public NodeIterator cloneIterator() {
  +	try {
  +	    final DupFilterIterator clone =
  +		(DupFilterIterator) super.clone();
  +	    clone._nodes = (IntegerArray) _nodes.clone();
  +	    clone._source = _source.cloneIterator();
  +	    clone._isRestartable = false;
  +	    return clone.reset();
  +	}
  +	catch (CloneNotSupportedException e) {
  +	    BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
  +				      e.toString());
  +	    return null;
  +	}
  +    }
  +
  +    public void setRestartable(boolean isRestartable) {
  +	_isRestartable = isRestartable;
  +	_source.setRestartable(isRestartable);
       }
   
  -    /**
  -     * Saves the position of this iterator - see gotoMark()
  -     */
       public void setMark() {
  -	_source.setMark();
   	_markedNode = _current;
       }
   
  -    /**
  -     * Restores the position of this iterator - see setMark()
  -     */
       public void gotoMark() {
  -	_source.gotoMark();
   	_current = _markedNode;
       }
   
       public NodeIterator reset() {
   	_current = 0;
  -	return(this);
  +	_lastNext = END;
  +	return resetPosition();
       }
  -
   }
  
  
  
  1.5       +27 -3     xml-xalan/java/src/org/apache/xalan/xsltc/dom/FilterIterator.java
  
  Index: FilterIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/FilterIterator.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- FilterIterator.java	4 Dec 2001 10:30:07 -0000	1.4
  +++ FilterIterator.java	8 Oct 2002 21:44:14 -0000	1.5
  @@ -66,13 +66,32 @@
   import org.apache.xalan.xsltc.NodeIterator;
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
   
  +/**
  + * Similar to a CurrentNodeListIterator except that the filter has a 
  + * simpler interface (only needs the node, no position, last, etc.)  
  + * It takes a source iterator and a Filter object and returns nodes 
  + * from the source after filtering them by calling filter.test(node).
  + */
   public final class FilterIterator extends NodeIteratorBase {
  +
  +    /**
  +     * Reference to source iterator.
  +     */
       private NodeIterator _source;
  +
  +    /**
  +     * Reference to a filter object that to be applied to each node.
  +     */
       private final Filter _filter;
  +
  +    /**
  +     * A flag indicating if position is reversed.
  +     */
       private final boolean _isReverse;
   	
       public FilterIterator(NodeIterator source, Filter filter) {
   	_source = source;
  +// System.out.println("FI souce = " + source + " this = " + this);
   	_filter = filter;
   	_isReverse = source.isReverse();
       }
  @@ -88,9 +107,9 @@
   
       public NodeIterator cloneIterator() {
   	try {
  -	    final FilterIterator clone = (FilterIterator)super.clone();
  -	    clone.setRestartable(false);
  +	    final FilterIterator clone = (FilterIterator) super.clone();
   	    clone._source = _source.cloneIterator();
  +	    clone._isRestartable = false;
   	    return clone.reset();
   	}
   	catch (CloneNotSupportedException e) {
  @@ -121,6 +140,11 @@
   	    return resetPosition();
   	}
   	return this;
  +    }
  +
  +    public int getPosition() {
  +	final int last = getLast();
  +	return _isReverse ? last - _position + 1 : _position;
       }
   
       public void setMark() {
  
  
  
  1.6       +8 -20     xml-xalan/java/src/org/apache/xalan/xsltc/dom/FilteredStepIterator.java
  
  Index: FilteredStepIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/FilteredStepIterator.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- FilteredStepIterator.java	4 Dec 2001 10:30:07 -0000	1.5
  +++ FilteredStepIterator.java	8 Oct 2002 21:44:14 -0000	1.6
  @@ -67,6 +67,10 @@
   import org.apache.xalan.xsltc.NodeIterator;
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
   
  +/**
  + * Extends a StepIterator by adding the ability to filter nodes. It 
  + * uses filters similar to those of a FilterIterator.
  + */
   public final class FilteredStepIterator extends StepIterator {
   
       private Filter _filter;
  @@ -78,30 +82,14 @@
   	_filter = filter;
       }
   
  -    public NodeIterator cloneIterator() {
  -	try {
  -	    final FilteredStepIterator clone =
  -		(FilteredStepIterator)super.clone();
  -	    clone._source = _source.cloneIterator();
  -	    clone._iterator = _iterator.cloneIterator();
  -	    clone._filter = _filter;
  -	    clone.setRestartable(false);
  -	    return clone.reset();
  -	}
  -	catch (CloneNotSupportedException e) {
  -	    BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
  -				      e.toString());
  -	    return null;
  -	}
  -    }
  -
       public int next() {
   	int node;
   	while ((node = super.next()) != END) {
  -	    if (_filter.test(node))
  +	    if (_filter.test(node)) {
   		return returnNode(node);
  +	    }
   	}
  -	return(node);
  +	return node;
       }
   
   }
  
  
  
  1.8       +63 -80    xml-xalan/java/src/org/apache/xalan/xsltc/dom/KeyIndex.java
  
  Index: KeyIndex.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/KeyIndex.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- KeyIndex.java	4 Dec 2001 10:30:07 -0000	1.7
  +++ KeyIndex.java	8 Oct 2002 21:44:14 -0000	1.8
  @@ -67,60 +67,48 @@
   
   import org.apache.xalan.xsltc.DOM;
   import org.apache.xalan.xsltc.NodeIterator;
  +import org.apache.xalan.xsltc.dom.NodeIteratorBase;
   import org.apache.xalan.xsltc.runtime.Hashtable;
  +import org.apache.xalan.xsltc.util.IntegerArray;
   
  -public class KeyIndex implements NodeIterator {
  +public class KeyIndex extends NodeIteratorBase {
   
       private Hashtable _index = new Hashtable();
  -    private BitArray  _nodes = null;
  -    private int       _pos = 0;
  +    // private BitArray  _nodes = null;
  +    private IntegerArray _nodes = null;
       private int       _mark = 0;
       private int       _save = 0;
       private int       _start = 0;
  -    private int       _arraySize = 0;
       private int       _node = -1;
   
  -    /**
  -     * Creates an index for a key defined by xsl:key
  -     */
  -    public KeyIndex(int size) {
  -	_arraySize = size;
  +    public KeyIndex(int dummy) {
       }
   
  -    public void setRestartable(boolean flag) {
  -	    
  -    }
  - 
       /**
        * Adds a node to the node list for a given value.
  -     * The BitArray object makes sure duplicate nodes are eliminated.
        */
       public void add(Object value, int node) {
  -	if ((_nodes = (BitArray)_index.get(value)) == null) {
  -	    _nodes = new BitArray(_arraySize);
  -	    _nodes.setMask(node & 0xff000000);
  -	    _index.put(value,_nodes);
  -	}
  -	_nodes.setBit(node & 0x00ffffff);
  -
  -	/*
  -	 * TODO: A bit array can currently only hold nodes from one DOM.
  -	 * An index will therefore only return nodes from a single document.
  -	 */
  +// System.out.println("KeyIndex.add() value = " + value + " node = " + node);
  +
  +	if ((_nodes = (IntegerArray) _index.get(value)) == null) {
  +	    _index.put(value, _nodes = new IntegerArray());
  +	}
  +	_nodes.add(node);
       }
   
       /**
        * Merge this node set with nodes from another index
        */
       public void merge(KeyIndex other) {
  -	// Only merge if other node set is not empty
  -	if (other != null) {
  -	    if (other._nodes != null) {
  -		// Create new Vector for nodes if this set is empty
  -		if (_nodes == null)
  -		    _nodes = other._nodes;
  -		else
  -		    _nodes = _nodes.merge(other._nodes);
  +// System.out.println("KeyIndex.merge()");
  +	if (other == null) return;
  +
  +	if (other._nodes != null) {
  +	    if (_nodes == null) {
  +		_nodes = other._nodes;
  +	    }
  +	    else {
  +		_nodes.merge(other._nodes);
   	    }
   	}
       }
  @@ -133,23 +121,29 @@
        * key() function.
        */
       public void lookupId(Object value) {
  +// System.out.println("KeyIndex.lookupId()");
   	if (value instanceof String) {
   	    final String string = (String)value;
   	    if (string.indexOf(' ') > -1) {
   		StringTokenizer values = new StringTokenizer(string);
  +
   		while (values.hasMoreElements()) {
  -		    BitArray nodes = (BitArray)_index.get(values.nextElement());
  +		    final IntegerArray nodes = 
  +			(IntegerArray)_index.get(values.nextElement());
  +
   		    if (nodes != null) {
  -			if (_nodes == null)
  +			if (_nodes == null) {
   			    _nodes = nodes;
  -			else
  -			    _nodes = _nodes.merge(nodes);
  +			}
  +			else {
  +			    _nodes.merge(nodes);
  +			}
   		    }
   		}
   		return;
   	    }
   	}
  -	_nodes = (BitArray)_index.get(value);
  +	_nodes = (IntegerArray) _index.get(value);
       }
   
       /**
  @@ -157,74 +151,76 @@
        * prior to returning the node iterator.
        */
       public void lookupKey(Object value) {
  -	_nodes = (BitArray)_index.get(value);
  +// System.out.println("KeyIndex.lookupKey() value = " + value);
  +	_nodes = (IntegerArray) _index.get(value);
  +	_position = 0;
       }
   
       /** 
        * Callers should not call next() after it returns END.
        */
       public int next() {
  -	if (_nodes == null) return(END);
  -	if ((_node = _nodes.getNextBit(++_node)) == END) return(END);
  -	_pos++;
  -	return(_node | _nodes.getMask());
  +// System.out.println("KeyIndex.next() _nodes = " + _nodes);
  +	if (_nodes == null) return END;
  +
  +	return (_position < _nodes.cardinality()) ? 
  +	    _nodes.at(_position++) : END;
       }
   
       public int containsID(int node, Object value) { 
   	if (value instanceof String) {
   	    final String string = (String)value;
   	    if (string.indexOf(' ') > -1) {
  -		StringTokenizer values = new StringTokenizer(string);
  +		final StringTokenizer values = new StringTokenizer(string);
  +
   		while (values.hasMoreElements()) {
  -		    BitArray nodes = (BitArray)_index.get(values.nextElement());
  -		    if ((nodes != null) && (nodes.getBit(node))) return(1);
  +		    final IntegerArray nodes = 
  +			(IntegerArray) _index.get(values.nextElement());
  +		    if (nodes != null && nodes.indexOf(node) >= 0) {
  +			return 1;
  +		    }
   		}
  -		return(0);
  +		return 0;
   	    }
   	}
   
  -	BitArray nodes = (BitArray)_index.get(value);
  -	if ((nodes != null) && (nodes.getBit(node))) return(1);
  -	return(0);
  +	final IntegerArray nodes = (IntegerArray) _index.get(value);
  +	return (nodes != null && nodes.indexOf(node) >= 0) ? 1 : 0;
       }
   
       public int containsKey(int node, Object value) { 
  -	BitArray nodes = (BitArray)_index.get(value);
  -	if ((nodes != null) && (nodes.getBit(node))) return(1);
  -	return(0);
  +	final IntegerArray nodes = (IntegerArray) _index.get(value);
  +	return (nodes != null && nodes.indexOf(node) >= 0) ? 1 : 0;
       }
   
       /**
        * Resets the iterator to the last start node.
        */
       public NodeIterator reset() {
  -	_pos = _start;
  +	_position = _start;
   	_node = _start - 1;
  -	return(this);
  +	return this;
       }
   
       /**
        * Returns the number of elements in this iterator.
        */
       public int getLast() {
  -	if (_nodes == null)
  -	    return(0);
  -	else
  -	    return(_nodes.size()); // TODO: count actual nodes
  +	return (_nodes == null) ? 0 : _nodes.cardinality();
       }
   
       /**
        * Returns the position of the current node in the set.
        */
       public int getPosition() {
  -	return(_pos);
  +	return _position;
       }
   
       /**
        * Remembers the current node for the next call to gotoMark().
        */
       public void setMark() {
  -	_mark = _pos;
  +	_mark = _position;
   	_save = _node;
       }
   
  @@ -232,7 +228,7 @@
        * Restores the current node remembered by setMark().
        */
       public void gotoMark() {
  -	_pos = _mark;
  +	_position = _mark;
   	_node = _save;
       }
   
  @@ -245,34 +241,21 @@
   	    _nodes = null;
   	}
   	else if (_nodes != null) {
  -	    // Node count starts with 1, while bit arrays count from 0. Must
  -	    // subtract one from 'start' to initialize bit array correctly.
  -	    _start = _nodes.getBitNumber(start-1); 
  -	    _node = _start - 1;
  +	    _position = 0;
   	}
  -	return((NodeIterator)this);
  -    }
  -
  -    /**
  -     * True if this iterator has a reversed axis.
  -     */
  -    public boolean isReverse() {
  -	return(false);
  +	return this;
       }
   
       /**
        * Returns a deep copy of this iterator.
        */
       public NodeIterator cloneIterator() {
  -	KeyIndex other = new KeyIndex(_arraySize);
  -
  +	KeyIndex other = new KeyIndex(0);
   	other._index = _index;
  -	other._nodes = _nodes.cloneArray();
  -	other._pos   = _pos;
  +	other._nodes = (_nodes == null) ? _nodes : (IntegerArray)_nodes.clone();
   	other._start = _start;
   	other._node  = _node;
  -
  -	return(other);
  +	return other;
       }
   
   }
  
  
  
  1.7       +42 -16    xml-xalan/java/src/org/apache/xalan/xsltc/dom/MatchingIterator.java
  
  Index: MatchingIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/MatchingIterator.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- MatchingIterator.java	4 Dec 2001 10:30:07 -0000	1.6
  +++ MatchingIterator.java	8 Oct 2002 21:44:14 -0000	1.7
  @@ -66,11 +66,36 @@
   import org.apache.xalan.xsltc.NodeIterator;
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
   
  +/**
  + * This is a special kind of iterator that takes a source iterator and a 
  + * node N. If initialized with a node M (the parent of N) it computes the 
  + * position of N amongst the children of M. This position can be obtained 
  + * by calling getPosition().
  + * It is an iterator even though next() will never be called. It is used to
  + * match patterns with a single predicate like:
  + *
  + *    BOOK[position() = last()]
  + *
  + * In this example, the source iterator will return elements of type BOOK, 
  + * a call to position() will return the position of N. Notice that because 
  + * of the way the pattern matching is implemented, N will always be a node 
  + * in the source since (i) it is a BOOK or the test sequence would not be 
  + * considered and (ii) the source iterator is initialized with M which is 
  + * the parent of N. Also, and still in this example, a call to last() will 
  + * return the number of elements in the source (i.e. the number of BOOKs).
  + */
   public final class MatchingIterator extends NodeIteratorBase {
  +
  +    /**
  +     * A reference to a source iterator.
  +     */
       private NodeIterator _source;
  -    private final int    _match;
  -    private int          _matchPos, _matchLast = -1;
  -	
  +
  +    /**
  +     * The node to match.
  +     */
  +    private final int _match;
  +
       public MatchingIterator(int match, NodeIterator source) {
   	_source = source;
   	_match = match;
  @@ -83,10 +108,10 @@
   
       public NodeIterator cloneIterator() {
   	try {
  -	    final MatchingIterator clone = (MatchingIterator)super.clone();
  +	    final MatchingIterator clone = (MatchingIterator) super.clone();
   	    clone._source = _source.cloneIterator();
  -	    clone.setRestartable(false);
  -	    return clone;
  +	    clone._isRestartable = false;
  +	    return clone.reset();
   	}
   	catch (CloneNotSupportedException e) {
   	    BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
  @@ -101,17 +126,17 @@
   	    _source.setStartNode(node);
   
   	    // Calculate the position of the node in the set
  -	    _matchPos = 1;
  -	    _matchLast = -1;
  -	    while ( ((node = _source.next()) != END) && (node != _match) )
  -		_matchPos++;
  +	    _position = 1; _last = -1;
  +	    while ((node = _source.next()) != END && node != _match) {
  +		_position++;
  +	    }
   	}
   	return this;
       }
   
       public NodeIterator reset() {
   	_source.reset();
  -	return this;
  +	return resetPosition();
       }
       
       public int next() {
  @@ -119,13 +144,14 @@
       }
   	
       public int getLast() {
  -	if (_matchLast == -1)
  -	    _matchLast = _source.getLast();
  -	return _matchLast;
  +	if (_last == -1) {
  +	    _last = _source.getLast();
  +	}
  +	return _last;
       }
   
       public int getPosition() {
  -	return _matchPos;
  +	return _position;
       }
   
       public void setMark() {
  
  
  
  1.21      +1 -9      xml-xalan/java/src/org/apache/xalan/xsltc/dom/MultiDOM.java
  
  Index: MultiDOM.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/MultiDOM.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- MultiDOM.java	21 Jun 2002 19:15:34 -0000	1.20
  +++ MultiDOM.java	8 Oct 2002 21:44:14 -0000	1.21
  @@ -355,14 +355,6 @@
   	return _adapters[node>>>24].getParent(node & CLR) | node&SET;
       }
       
  -    public int getTypedPosition(int type, int node) {
  -	return _adapters[node>>>24].getTypedPosition(type, node&CLR);
  -    }
  -
  -    public int getTypedLast(int type, int node) {
  -	return _adapters[node>>>24].getTypedLast(type, node&CLR);
  -    }
  -
       public int getAttributeNode(final int type, final int el) {
   	return _adapters[el>>>24].getAttributeNode(type, el&CLR) | el&SET;
       }
  
  
  
  1.8       +69 -3     xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeIteratorBase.java
  
  Index: NodeIteratorBase.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeIteratorBase.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- NodeIteratorBase.java	14 May 2002 22:12:00 -0000	1.7
  +++ NodeIteratorBase.java	8 Oct 2002 21:44:14 -0000	1.8
  @@ -68,18 +68,56 @@
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
   
   public abstract class NodeIteratorBase implements NodeIterator {
  -    private int _last = -1;
  +
  +    /**
  +     * Cached computed value of last().
  +     */
  +    protected int _last = -1;
  +
  +    /**
  +     * Value of position() in this iterator. Incremented in
  +     * returnNode().
  +     */
       protected int _position = 0;
   
  +    /**
  +     * Store node in call to setMark().
  +     */
       protected int _markedNode;
  +
  +    /**
  +     * Store node in call to setStartNode().
  +     */
       protected int _startNode = NodeIterator.END;
  +
  +    /** 
  +     * Flag indicating if "self" should be returned.
  +     */
       protected boolean _includeSelf = false;
  +
  +    /**
  +     * Flag indicating if iterator can be restarted.
  +     */
       protected boolean _isRestartable = true;
   
  +    /**
  +     * Setter for _isRestartable flag. 
  +     */
       public void setRestartable(boolean isRestartable) {
   	_isRestartable = isRestartable;
       }
   
  +    /**
  +     * Initialize iterator using a node. If iterator is not
  +     * restartable, then do nothing. If node is equal to END then
  +     * subsequent calls to next() must return END.
  +     */
  +    abstract public NodeIterator setStartNode(int node);
  +
  +    /**
  +     * Reset this iterator using state from last call to
  +     * setStartNode().
  +     */
       public NodeIterator reset() {
   	final boolean temp = _isRestartable;
   	_isRestartable = true;
  @@ -89,11 +127,19 @@
   	return this;
       }
   
  +    /**
  +     * Setter for _includeSelf flag.
  +     */
       public NodeIterator includeSelf() {
   	_includeSelf = true;
   	return this;
       }
   
  +    /**
  +     * Default implementation of getLast(). Stores current position
  +     * and current node, resets the iterator, counts all nodes and
  +     * restores iterator to original state.
  +     */
       public int getLast() {
   	if (_last == -1) {
   	    final int temp = _position;
  @@ -108,14 +154,28 @@
   	return _last;
       }
   
  +    /**
  +     * Returns the position() in this iterator.
  +     */
       public int getPosition() {
   	return _position == 0 ? 1 : _position;
       }
   
  +    /**
  +     * Indicates if position in this iterator is computed in reverse
  +     * document order. Note that nodes are always returned in document
  +     * order.
  +     */
       public boolean isReverse() {
   	return false;
       }
       
  +    /**
  +     * Clones and resets this iterator. Note that the cloned iterator is 
  +     * not restartable. This is because cloning is needed for variable 
  +     * references, and the context node of the original variable 
  +     * declaration must be preserved.
  +     */
       public NodeIterator cloneIterator() {
   	try {
   	    final NodeIteratorBase clone = (NodeIteratorBase)super.clone();
  @@ -129,14 +189,20 @@
   	}
       }
       
  +    /**
  +     * Utility method that increments position and returns its
  +     * argument.
  +     */
       protected final int returnNode(final int node) {
   	_position++;
   	return node;
       }
       
  +    /**
  +     * Reset the position in this iterator.
  +     */
       protected final NodeIterator resetPosition() {
   	_position = 0;
   	return this;
       }
  -
   }
  
  
  
  1.10      +21 -20    xml-xalan/java/src/org/apache/xalan/xsltc/dom/NthIterator.java
  
  Index: NthIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/NthIterator.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- NthIterator.java	4 Dec 2001 10:30:07 -0000	1.9
  +++ NthIterator.java	8 Oct 2002 21:44:14 -0000	1.10
  @@ -83,21 +83,33 @@
   	_source.setRestartable(isRestartable);
       }
       
  +    public NodeIterator cloneIterator() {
  +	try {
  +	    final NthIterator clone = (NthIterator) super.clone();
  +	    clone._source = _source.cloneIterator();	// resets source
  +	    clone._isRestartable = false;
  +	    return clone;
  +	}
  +	catch (CloneNotSupportedException e) {
  +	    BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
  +				      e.toString());
  +	    return null;
  +	}
  +    }
  +
       public int next() {
   	if (_ready && _position > 0) {
   	    _ready = false;
  -	    // skip N-1 nodes
  -	    final int pos = _position;
  -	    for (int n = pos - 1; n-- > 0;) {
  -		if (_source.next() == NodeIterator.END) {
  -		    return NodeIterator.END;
  +	    int node;
  +	    while ((node = _source.next()) != END) {
  +		if (_position == _source.getPosition()) {
  +		    return node;
   		}
   	    }
  -	    return _source.next();
   	}
  -	return NodeIterator.END;
  +	return END;
       }
  -	
  +
       public NodeIterator setStartNode(final int node) {
   	if (_isRestartable) {
   	    _source.setStartNode(node);
  @@ -120,22 +132,11 @@
   	return 1;
       }
       
  -    public boolean isReverse() {
  -	return _source.isReverse();
  -    }
  -    
       public void setMark() {
   	_source.setMark();
       }
       
       public void gotoMark() {
   	_source.gotoMark();
  -    }
  -
  -    public NodeIterator cloneIterator() {
  -	NodeIterator clone = _source.cloneIterator();
  -	NthIterator other = new NthIterator(clone, _position);
  -	other.setRestartable(false);
  -	return other.reset();
       }
   }
  
  
  
  1.13      +28 -4     xml-xalan/java/src/org/apache/xalan/xsltc/dom/StepIterator.java
  
  Index: StepIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/StepIterator.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- StepIterator.java	13 Jun 2002 12:43:49 -0000	1.12
  +++ StepIterator.java	8 Oct 2002 21:44:14 -0000	1.13
  @@ -68,29 +68,53 @@
   import org.apache.xalan.xsltc.NodeIterator;
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
   
  +/**
  + * A step iterator is used to evaluate expressions like "BOOK/TITLE". 
  + * A better name for this iterator would have been ParentIterator since 
  + * both "BOOK" and "TITLE" are steps in XPath lingo. Step iterators are 
  + * constructed from two other iterators which we are going to refer to 
  + * as "outer" and "inner". Every node from the outer iterator (the one 
  + * for BOOK in our example) is used to initialize the inner iterator. 
  + * After this initialization, every node from the inner iterator is 
  + * returned (in essence, implementing a "nested loop").
  + */
   public class StepIterator extends NodeIteratorBase {
   
  +    /**
  +     * A reference to the "outer" iterator.
  +     */
       protected NodeIterator _source;
  +
  +    /**
  +     * A reference to the "inner" iterator.
  +     */
       protected NodeIterator _iterator;
  +
  +    /**
  +     * Temp variable to store a marked position.
  +     */
       private int _pos = -1;
   
       public StepIterator(NodeIterator source, NodeIterator iterator) {
   	_source = source;
   	_iterator = iterator;
  +// System.out.println("SI source = " + source + " this = " + this);
  +// System.out.println("SI iterator = " + iterator + " this = " + this);
       }
   
       public void setRestartable(boolean isRestartable) {
   	_isRestartable = isRestartable;
   	_source.setRestartable(isRestartable);
  -	_iterator.setRestartable(true); // must _always_ be restartable
  +	_iterator.setRestartable(true); 	// must be restartable
       }
   
       public NodeIterator cloneIterator() {
   	try {
  -	    final StepIterator clone = (StepIterator)super.clone();
  +	    final StepIterator clone = (StepIterator) super.clone();
   	    clone._source = _source.cloneIterator();
   	    clone._iterator = _iterator.cloneIterator();
  -	    clone.setRestartable(false);
  +	    clone._iterator.setRestartable(true); 	// must be restartable
  +	    clone._isRestartable = false;
   	    return clone.reset();
   	}
   	catch (CloneNotSupportedException e) {
  
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/xsltc/dom/ForwardPositionIterator.java
  
  Index: ForwardPositionIterator.java
  ===================================================================
  /*
   * @(#)$Id: ForwardPositionIterator.java,v 1.1 2002/10/08 21:44:14 santiagopg Exp $
   *
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2001, Sun
   * Microsystems., http://www.sun.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * @author Santiago Pericas-Geertsen
   *
   */
  
  package org.apache.xalan.xsltc.dom;
  
  import org.apache.xalan.xsltc.NodeIterator;
  import org.apache.xalan.xsltc.runtime.BasisLibrary;
  
  /**
   * This iterator is a wrapper that always returns the position of
   * a node in document order. It is needed for the case where 
   * a call to position() occurs in the context of an XSLT element
   * such as xsl:for-each, xsl:apply-templates, etc. 
   */
  public final class ForwardPositionIterator extends NodeIteratorBase {
  
      private NodeIterator _source;
  
      public ForwardPositionIterator(NodeIterator source) {
  	_source = source;
      }
  
      public NodeIterator cloneIterator() {
  	try {
  	    final ForwardPositionIterator clone = 
  		(ForwardPositionIterator) super.clone();
  	    clone._source = _source.cloneIterator();
  	    clone._isRestartable = false;
  	    return clone.reset();
  	}
  	catch (CloneNotSupportedException e) {
  	    BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
  				      e.toString());
  	    return null;
  	}
      }
  
      public int next() {
  	return returnNode(_source.next());
      }
  	
      public NodeIterator setStartNode(int node) {
  	_source.setStartNode(node);
  	return this;
      }
  
      public NodeIterator reset() {
  	_source.reset();
  	return resetPosition();
      }
  
      public int getPosition() {
  	return _position == 0 ? 1 : _position;
      }
  
      public void setMark() {
  	_source.setMark();
      }
  
      public void gotoMark() {
  	_source.gotoMark();
      }
  }
  
  
  
  1.3       +53 -2     xml-xalan/java/src/org/apache/xalan/xsltc/util/IntegerArray.java
  
  Index: IntegerArray.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/util/IntegerArray.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- IntegerArray.java	26 Jun 2002 19:03:06 -0000	1.2
  +++ IntegerArray.java	8 Oct 2002 21:44:15 -0000	1.3
  @@ -120,12 +120,63 @@
   	_array[_free++] = value;
       }
     
  -    /** adds new int at the end if not already present */
  +    /** 
  +     * Adds new int at the end if not already present.
  +     */
       public void addNew(int value) {
   	for (int i = 0; i < _free; i++) {
   	    if (_array[i] == value) return;  // already in array
   	}
   	add(value);
  +    }
  +
  +    public void reverse() {
  +	int left = 0; 
  +	int right = _free - 1;
  +
  +	while (left < right) {
  +	    int temp = _array[left];
  +	    _array[left++] = _array[right];
  +	    _array[right--] = temp;
  +	}
  +    }
  +
  +    public void merge(IntegerArray array) {
  +	final int n = array._free;
  +	for (int i = 0; i < n; i++) {
  +	    addNew(array.at(i));
  +	}
  +	sort();		// must be sorted
  +    }
  +
  +    public void sort() {
  +	quicksort(_array, 0, _free - 1);
  +    }
  +
  +    private static void quicksort(int[] array, int p, int r) {
  +	if (p < r) {
  +	    final int q = partition(array, p, r);
  +	    quicksort(array, p, q);
  +	    quicksort(array, q + 1, r);
  +	}
  +    }
  +    
  +    private static int partition(int[] array, int p, int r) {
  +	final int x = array[p];
  +	int i = p - 1; int j = r + 1;
  +
  +	while (true) {
  +	    while (x < array[--j]);
  +	    while (x > array[++i]);
  +	    if (i < j) {
  +		int temp = array[i];
  +		array[i] = array[j];
  +		array[j] = temp;
  +	    }
  +	    else {
  +		return j;
  +	    }
  +	}
       }
   
       private void growArray(int size) {
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org