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 [EMAIL PROTECTED]
   *
   * 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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to