You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sb...@apache.org on 2001/06/11 22:17:18 UTC

cvs commit: xml-xalan/java/src/org/apache/xpath/patterns FunctionPattern.java NodeTest.java StepPattern.java UnionPattern.java

sboag       01/06/11 13:17:17

  Modified:    java/src/org/apache/xalan/processor Tag: DTM_EXP
                        ProcessorTemplate.java ProcessorTemplateElem.java
                        StylesheetHandler.java XSLTSchema.java
               java/src/org/apache/xalan/serialize Tag: DTM_EXP
                        SerializerToHTML.java
               java/src/org/apache/xalan/templates Tag: DTM_EXP AVT.java
                        AVTPart.java AVTPartSimple.java AVTPartXPath.java
                        ElemApplyTemplates.java ElemCallTemplate.java
                        ElemChoose.java ElemCopy.java ElemCopyOf.java
                        ElemElement.java ElemExtensionCall.java
                        ElemForEach.java ElemIf.java ElemLiteralResult.java
                        ElemNumber.java ElemPI.java ElemParam.java
                        ElemSort.java ElemTemplate.java
                        ElemTemplateElement.java ElemValueOf.java
                        ElemVariable.java ElemWhen.java ElemWithParam.java
                        KeyDeclaration.java OutputProperties.java
                        StylesheetRoot.java TemplateList.java
                        XUnresolvedVariable.java
               java/src/org/apache/xalan/transformer Tag: DTM_EXP
                        KeyRefIterator.java TransformerImpl.java
               java/src/org/apache/xml/dtm Tag: DTM_EXP Axis.java
               java/src/org/apache/xml/dtm/ref Tag: DTM_EXP
                        DTMDefaultBase.java DTMDefaultBaseTraversers.java
                        DTMManagerDefault.java
               java/src/org/apache/xml/dtm/ref/sax2dtm Tag: DTM_EXP
                        SAX2DTM.java
               java/src/org/apache/xpath Tag: DTM_EXP Arg.java
                        Expression.java VariableStack.java XPath.java
                        XPathContext.java
               java/src/org/apache/xpath/axes Tag: DTM_EXP
                        ChildTestIterator.java DescendantIterator.java
                        FilterExprWalker.java LocPathIterator.java
                        MatchPatternIterator.java
                        OneStepIteratorForward.java PredicatedNodeTest.java
                        UnionPathIterator.java WalkingIterator.java
                        WalkingIteratorSorted.java
               java/src/org/apache/xpath/functions Tag: DTM_EXP
                        FuncCurrent.java FuncExtFunction.java
                        FuncFalse.java FuncLast.java FuncPosition.java
                        FuncSubstring.java FuncTrue.java Function.java
                        Function2Args.java Function3Args.java
                        FunctionMultiArgs.java FunctionOneArg.java
               java/src/org/apache/xpath/objects Tag: DTM_EXP XNodeSet.java
                        XNumber.java XObject.java XRTreeFrag.java
                        XString.java XStringForFSB.java
               java/src/org/apache/xpath/operations Tag: DTM_EXP And.java
                        Bool.java Div.java Minus.java Mod.java Mult.java
                        Neg.java Number.java Operation.java Or.java
                        Plus.java String.java UnaryOperation.java
                        Variable.java
               java/src/org/apache/xpath/patterns Tag: DTM_EXP
                        FunctionPattern.java NodeTest.java StepPattern.java
                        UnionPattern.java
  Added:       java/src/org/apache/xpath/objects Tag: DTM_EXP
                        XRTreeFragSelectWrapper.java
  Removed:     java/src/org/apache/xalan/processor Tag: DTM_EXP
                        CompiledStylesheetBundle.java CompiledTemplate.java
                        CompilingStylesheetHandler.java
                        CompilingStylesheetProcessor.java
  Log:
  This check-in is probably too large to rightfully do in a single commit.  Sorry.
  The variable mechanism is been redone, so that references do
  direct index lookup, instead of lookup by QName comparison.  The
  variable stack is completely redesigned so that link/unlink is called
  on the stack before an apply templates or call templates.  I still don't
  like how parameters are being pushed on the stack... but I'm not
  sure there's a viable alternative.  All the static variable resolution is
  done in the compose() methods, which is different from the original
  design I posted to the list.
  
  transformSelectedNodes is now implemented seperately in ElemApplyTemplates
  and ElemForEach... they no longer share the function.
  
  A bug was  fixed in relation to problems discovered running
  the datapower suite: UnionPaths had trouble sorting.
  
  Other tweaks for performance were made.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.6.2.1   +1 -1      xml-xalan/java/src/org/apache/xalan/processor/ProcessorTemplate.java
  
  Index: ProcessorTemplate.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/ProcessorTemplate.java,v
  retrieving revision 1.6
  retrieving revision 1.6.2.1
  diff -u -r1.6 -r1.6.2.1
  --- ProcessorTemplate.java	2000/11/22 23:25:56	1.6
  +++ ProcessorTemplate.java	2001/06/11 20:16:05	1.6.2.1
  @@ -67,7 +67,7 @@
    */
   class ProcessorTemplate extends ProcessorTemplateElem
   {
  -
  +  
     /**
      * Append the current template element to the current
      * template element, and then push it onto the current template
  
  
  
  1.7.2.1   +2 -2      xml-xalan/java/src/org/apache/xalan/processor/ProcessorTemplateElem.java
  
  Index: ProcessorTemplateElem.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/ProcessorTemplateElem.java,v
  retrieving revision 1.7
  retrieving revision 1.7.2.1
  diff -u -r1.7 -r1.7.2.1
  --- ProcessorTemplateElem.java	2001/03/29 22:39:33	1.7
  +++ ProcessorTemplateElem.java	2001/06/11 20:16:05	1.7.2.1
  @@ -93,7 +93,7 @@
               throws org.xml.sax.SAXException
     {
   
  -		super.startElement(handler, uri, localName, rawName, attributes);
  +    super.startElement(handler, uri, localName, rawName, attributes);
       try
       {
         // ElemTemplateElement parent = handler.getElemTemplateElement();
  @@ -164,7 +164,7 @@
             StylesheetHandler handler, String uri, String localName, String rawName)
               throws org.xml.sax.SAXException
     {
  -		super.endElement(handler, uri, localName, rawName);
  +    super.endElement(handler, uri, localName, rawName);
       handler.popElemTemplateElement();
     }
   }
  
  
  
  1.39.2.1  +7 -7      xml-xalan/java/src/org/apache/xalan/processor/StylesheetHandler.java
  
  Index: StylesheetHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/StylesheetHandler.java,v
  retrieving revision 1.39
  retrieving revision 1.39.2.1
  diff -u -r1.39 -r1.39.2.1
  --- StylesheetHandler.java	2001/03/29 22:39:33	1.39
  +++ StylesheetHandler.java	2001/06/11 20:16:05	1.39.2.1
  @@ -404,7 +404,7 @@
               && ((null == getStylesheet()
                   || Double.valueOf(getStylesheet().getVersion()).doubleValue()
                      > Constants.XSLTVERSUPPORTED) ||
  -								(!uri.equals(Constants.S_XSLNAMESPACEURL) &&
  +                                                                (!uri.equals(Constants.S_XSLNAMESPACEURL) &&
                   currentProcessor instanceof ProcessorStylesheetElement)))
       {
         elemProcessor = def.getProcessorForUnknown(uri, localName);
  @@ -413,7 +413,7 @@
       if (null == elemProcessor)
         error(rawName + " is not allowed in this position in the stylesheet!",
               null);
  -		
  +                
       return elemProcessor;
     }
   
  @@ -600,7 +600,7 @@
             String uri, String localName, String rawName, Attributes attributes)
               throws org.xml.sax.SAXException
     {
  -		NamespaceSupport nssupport = this.getNamespaceSupport();
  +                NamespaceSupport nssupport = this.getNamespaceSupport();
       nssupport.pushContext();
       
       int n = m_prefixMappings.size();
  @@ -629,7 +629,7 @@
   
       this.pushProcessor(elemProcessor);
       elemProcessor.startElement(this, uri, localName, rawName, attributes);
  -		
  +                
     }
   
     /**
  @@ -1140,8 +1140,8 @@
   
     /** The root stylesheet of the stylesheets tree. */
     StylesheetRoot m_stylesheetRoot;
  -	
  -	/** The last stylesheet that was popped off the stylesheets stack. */
  +        
  +        /** The last stylesheet that was popped off the stylesheets stack. */
     Stylesheet m_lastPoppedStylesheet;
   
     /**
  @@ -1256,7 +1256,7 @@
       {
         return null;
       }
  -  }
  +  }  
   
     /** An increasing number that is used to indicate the order in which this element
      *  was encountered during the parse of the XSLT tree.
  
  
  
  1.19.2.2  +27 -27    xml-xalan/java/src/org/apache/xalan/processor/XSLTSchema.java
  
  Index: XSLTSchema.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/XSLTSchema.java,v
  retrieving revision 1.19.2.1
  retrieving revision 1.19.2.2
  diff -u -r1.19.2.1 -r1.19.2.2
  --- XSLTSchema.java	2001/05/27 03:05:13	1.19.2.1
  +++ XSLTSchema.java	2001/06/11 20:16:06	1.19.2.2
  @@ -282,7 +282,7 @@
                                          xslVersionAttr,
                                          xslResultAttr,
                                          resultAttr }, 
  -																		 new ProcessorLRE(),
  +                                        new ProcessorLRE(),
                                        ElemLiteralResult.class /* class object */, 20, true);
       XSLTElementDef unknownElement =
         new XSLTElementDef(this, "*", "unknown", null /*alias */,
  @@ -293,14 +293,14 @@
                                                    xslVersionAttr,
                                                    xslResultAttr,
                                                    resultAttr }, 
  -												 new ProcessorUnknown(),
  +                                                                                                 new ProcessorUnknown(),
                            ElemUnknown.class /* class object */, 20, true);
       XSLTElementDef xslValueOf = new XSLTElementDef(this,
                                     Constants.S_XSLNAMESPACEURL, "value-of",
                                     null /*alias */, null /* elements */,
                                     new XSLTAttributeDef[]{ selectAttrRequired,
                                                             disableOutputEscapingAttr }, 
  -																	new ProcessorTemplateElem(),
  +                                               new ProcessorTemplateElem(),
                                     ElemValueOf.class /* class object */, 20, true);
       XSLTElementDef xslCopyOf = new XSLTElementDef(this,
                                    Constants.S_XSLNAMESPACEURL, "copy-of",
  @@ -320,7 +320,7 @@
                                                            letterValueAttr,
                                                            groupingSeparatorAVT,
                                                            groupingSizeAttr }, 
  -																 new ProcessorTemplateElem(),
  +                                        new ProcessorTemplateElem(),
                                    ElemNumber.class /* class object */, 20, true);
   
       // <!-- xsl:sort cannot occur after any other elements or
  @@ -335,7 +335,7 @@
                                                     dataTypeAttr,
                                                     orderAttr,
                                                     caseOrderAttr }, 
  -																								new ProcessorTemplateElem(),
  +                                       new ProcessorTemplateElem(),
                                                   ElemSort.class/* class object */, 19, true );
       XSLTElementDef xslWithParam = new XSLTElementDef(this,
                                       Constants.S_XSLNAMESPACEURL,
  @@ -351,7 +351,7 @@
                                                                  xslWithParam } /* elements */, new XSLTAttributeDef[]{
                                                                    selectAttrDefNode,
                                                                    modeAttr }, 
  -																				 new ProcessorTemplateElem(),
  +                                                                        new ProcessorTemplateElem(),
                                            ElemApplyTemplates.class /* class object */, 20, true);
       XSLTElementDef xslApplyImports =
         new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "apply-imports",
  @@ -364,7 +364,7 @@
                                     null /*alias */, templateElementsAndSort,  // (#PCDATA %instructions; %result-elements; | xsl:sort)*
                                     new XSLTAttributeDef[]{ selectAttrRequired,
                                                             spaceAttr }, 
  -																	new ProcessorTemplateElem(),
  +                                               new ProcessorTemplateElem(),
                                     ElemForEach.class /* class object */, true, false, true, 20, true);
       XSLTElementDef xslIf = new XSLTElementDef(this,
                                                 Constants.S_XSLNAMESPACEURL,
  @@ -381,7 +381,7 @@
                                                     testAttrRequired,
                                                     spaceAttr }, new ProcessorTemplateElem(),
                                                                  ElemWhen.class /* class object */,
  -																															 false, true, 1, true);
  +                                                                                                false, true, 1, true);
       XSLTElementDef xslOtherwise = new XSLTElementDef(this,
                                       Constants.S_XSLNAMESPACEURL, "otherwise",
                                       null /*alias */,
  @@ -389,13 +389,13 @@
                                       new XSLTAttributeDef[]{ spaceAttr },
                                       new ProcessorTemplateElem(),
                                       ElemOtherwise.class /* class object */,
  -																		false, false, 2, false);
  +                                                       false, false, 2, false);
       XSLTElementDef xslChoose = new XSLTElementDef(this,
                                    Constants.S_XSLNAMESPACEURL, "choose",
                                    null /*alias */,
                                    new XSLTElementDef[]{ xslWhen,
                                                          xslOtherwise } /* elements */, 
  -																 new XSLTAttributeDef[]{ spaceAttr },
  +                                        new XSLTAttributeDef[]{ spaceAttr },
                                    new ProcessorTemplateElem(),
                                    ElemChoose.class /* class object */, true, false, true, 20, true);                                
       XSLTElementDef xslAttribute = new XSLTElementDef(this,
  @@ -405,7 +405,7 @@
                                       new XSLTAttributeDef[]{ nameAVTRequired,
                                                               namespaceAVTOpt,
                                                               spaceAttr }, 
  -																		new ProcessorTemplateElem(),
  +                                    new ProcessorTemplateElem(),
                                       ElemAttribute.class /* class object */, 20, true);
       XSLTElementDef xslCallTemplate =
         new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "call-template",
  @@ -420,7 +420,7 @@
                                      templateElements /* elements */,  // %template;>
                                      new XSLTAttributeDef[]{ nameAttrRequired,
                                                              selectAttrOpt }, 
  -																	 new ProcessorTemplateElem(),
  +                                  new ProcessorTemplateElem(),
                                      ElemVariable.class /* class object */, 20, true);
       XSLTElementDef xslParam = new XSLTElementDef(this,
                                   Constants.S_XSLNAMESPACEURL, "param",
  @@ -428,7 +428,7 @@
                                   templateElements /* elements */,  // %template;>
                                   new XSLTAttributeDef[]{ nameAttrRequired,
                                                           selectAttrOpt }, 
  -																new ProcessorTemplateElem(),
  +                                       new ProcessorTemplateElem(),
                                   ElemParam.class /* class object */, 19, true);
       XSLTElementDef xslText =
         new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "text",
  @@ -444,7 +444,7 @@
                            new XSLTAttributeDef[]{
                                                     nameAVTRequired,
                                                     spaceAttr }, 
  -													new ProcessorTemplateElem(),
  +                                        new ProcessorTemplateElem(),
                             ElemPI.class /* class object */, 20, true);
       XSLTElementDef xslElement = new XSLTElementDef(this,
                                     Constants.S_XSLNAMESPACEURL, "element",
  @@ -454,7 +454,7 @@
                                                             namespaceAVTOpt,
                                                             useAttributeSetsAttr,
                                                             spaceAttr }, 
  -																	new ProcessorTemplateElem(),
  +                                               new ProcessorTemplateElem(),
                                     ElemElement.class /* class object */, 20, true);
       XSLTElementDef xslComment = new XSLTElementDef(this,
                                     Constants.S_XSLNAMESPACEURL, "comment",
  @@ -469,7 +469,7 @@
                             new XSLTAttributeDef[]{
                                                     spaceAttr,
                                                     useAttributeSetsAttr }, 
  -													new ProcessorTemplateElem(),
  +                                        new ProcessorTemplateElem(),
                             ElemCopy.class /* class object */, 20, true);
       XSLTElementDef xslMessage = new XSLTElementDef(this,
                                     Constants.S_XSLNAMESPACEURL, "message",
  @@ -553,14 +553,14 @@
                                    new XSLTAttributeDef[]{ hrefAttr },  // EMPTY
                                    new ProcessorImport(),
                                    null /* class object */,
  -																 1, true);
  +                                        1, true);
       XSLTElementDef includeDef = new XSLTElementDef(this,
                                     Constants.S_XSLNAMESPACEURL, "include",
                                     null /*alias */, null /* elements */,  // EMPTY
                                     new XSLTAttributeDef[]{ hrefAttr },
                                     new ProcessorInclude(),
                                     null /* class object */,
  -																	20, true);
  +                                               20, true);
       XSLTElementDef[] topLevelElements = new XSLTElementDef[]{ includeDef,
                                                                 importDef,
                                                                 // resultElement,
  @@ -605,7 +605,7 @@
                                                                     mediaTypeAttr,
                                                                     XSLTAttributeDef.m_foreignAttr }, 
                                                                   new ProcessorOutputElem(), null /* class object */, 20, true), 
  -																				                      new XSLTElementDef(
  +                                                                                             new XSLTElementDef(
                                                                       this,
                                                                       Constants.S_XSLNAMESPACEURL,
                                                                       "key",
  @@ -614,7 +614,7 @@
                                                                       new XSLTAttributeDef[]{ nameAttrRequired,
                                                                                               matchAttrRequired,
                                                                                               useAttr }, 
  -																				                        new ProcessorKey(), null /* class object */, 20, true),
  +                                                                                               new ProcessorKey(), null /* class object */, 20, true),
                                                                 new XSLTElementDef(
                                                                   this,
                                                                   Constants.S_XSLNAMESPACEURL,
  @@ -633,7 +633,7 @@
                                                                                      zeroDigitAttr,
                                                                                      digitAttr,
                                                                                      patternSeparatorAttr }, 
  -																				                        new ProcessorDecimalFormat(),
  +                                                                                               new ProcessorDecimalFormat(),
                                                                   null /* class object */, 20, true),
                                                                 new XSLTElementDef(
                                                                   this,
  @@ -678,7 +678,7 @@
                                                                     priorityAttr,
                                                                     modeAttr,
                                                                     spaceAttr }, new ProcessorTemplate(), ElemTemplate.class /* class object */, 20, true), 
  -																				                      new XSLTElementDef(
  +                                                                                             new XSLTElementDef(
                                                                       this,
                                                                       Constants.S_XSLNAMESPACEURL,
                                                                       "namespace-alias",
  @@ -686,7 +686,7 @@
                                                                       null /* elements */,  // EMPTY
                                                                       new XSLTAttributeDef[]{ stylesheetPrefixAttr,
                                                                                               resultPrefixAttr }, 
  -																				                            new ProcessorNamespaceAlias(), null /* class object */, 20, true),
  +                                                                                                   new ProcessorNamespaceAlias(), null /* class object */, 20, true),
                                                                 new XSLTElementDef(
                                                                   this,
                                                                   Constants.S_BUILTIN_EXTENSIONS_URL,
  @@ -706,11 +706,11 @@
                                                                           XSLTAttributeDef.T_NMTOKEN,
                                                                           true),
                                                                         new XSLTAttributeDef(null, "src", XSLTAttributeDef.T_URL, false) }, 
  -																				                           new ProcessorLRE(),
  +                                                                                                  new ProcessorLRE(),
                                                                      ElemExtensionScript.class /* class object */, 20, true) },  // EMPTY
  -                                                                                                                                                                                                                                                                                                                                                new XSLTAttributeDef[]{ new XSLTAttributeDef(null, "prefix", XSLTAttributeDef.T_NMTOKEN, true),
  -                                                                                                                                                                                                                                                                                                                                                                        new XSLTAttributeDef(null, "elements", XSLTAttributeDef.T_STRINGLIST, false),
  -                                                                                                                                                                                                                                                                                                                                                                        new XSLTAttributeDef(null, "functions", XSLTAttributeDef.T_STRINGLIST, false) }, new ProcessorLRE(), ElemExtensionDecl.class /* class object */) };
  +                                                                                              new XSLTAttributeDef[]{ new XSLTAttributeDef(null, "prefix", XSLTAttributeDef.T_NMTOKEN, true),
  +                                                                                                                      new XSLTAttributeDef(null, "elements", XSLTAttributeDef.T_STRINGLIST, false),
  +                                                                                                                      new XSLTAttributeDef(null, "functions", XSLTAttributeDef.T_STRINGLIST, false) }, new ProcessorLRE(), ElemExtensionDecl.class /* class object */) };
       XSLTAttributeDef excludeResultPrefixesAttr =
         new XSLTAttributeDef(null, "exclude-result-prefixes",
                              XSLTAttributeDef.T_STRINGLIST, false);
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.2.2.2   +7 -0      xml-xalan/java/src/org/apache/xalan/serialize/SerializerToHTML.java
  
  Index: SerializerToHTML.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/serialize/SerializerToHTML.java,v
  retrieving revision 1.2.2.1
  retrieving revision 1.2.2.2
  diff -u -r1.2.2.1 -r1.2.2.2
  --- SerializerToHTML.java	2001/06/03 03:18:05	1.2.2.1
  +++ SerializerToHTML.java	2001/06/11 20:16:09	1.2.2.2
  @@ -593,6 +593,7 @@
         accum(
           "<META http-equiv=\"Content-Type\" content=\"text/html; charset=");
   
  +      // String encoding = Encodings.getMimeEncoding(m_encoding).toLowerCase();
         String encoding = Encodings.getMimeEncoding(m_encoding);
   
         accum(encoding);
  @@ -819,6 +820,12 @@
             // Reference is Unicode, A Primer, by Tony Graham.
             // Page 92.
             
  +          // Note that Kay doesn't escape 0x20...
  +          //  if(ch == 0x20) // Not sure about this... -sb
  +          //  {
  +          //    accum(ch);
  +          //  }
  +          //  else 
             if(ch <= 0x7F)
             {
               accum('%');
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.13.2.2  +25 -0     xml-xalan/java/src/org/apache/xalan/templates/AVT.java
  
  Index: AVT.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/AVT.java,v
  retrieving revision 1.13.2.1
  retrieving revision 1.13.2.2
  diff -u -r1.13.2.1 -r1.13.2.2
  --- AVT.java	2001/04/10 18:44:44	1.13.2.1
  +++ AVT.java	2001/06/11 20:16:10	1.13.2.2
  @@ -576,4 +576,29 @@
   
       return false;
     }
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    if (null != m_parts)
  +    {
  +      int n = m_parts.size();
  +
  +      for (int i = 0; i < n; i++)
  +      {
  +        AVTPart part = (AVTPart) m_parts.elementAt(i);
  +
  +        part.fixupVariables(vars, globalsSize);
  +      }
  +    }
  +  }
   }
  
  
  
  1.9.2.2   +13 -0     xml-xalan/java/src/org/apache/xalan/templates/AVTPart.java
  
  Index: AVTPart.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/AVTPart.java,v
  retrieving revision 1.9.2.1
  retrieving revision 1.9.2.2
  diff -u -r1.9.2.1 -r1.9.2.2
  --- AVTPart.java	2001/04/10 18:44:45	1.9.2.1
  +++ AVTPart.java	2001/06/11 20:16:10	1.9.2.2
  @@ -116,5 +116,18 @@
      {
       return false;
      }
  +   
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public abstract void fixupVariables(java.util.Vector vars, int globalsSize);
  +
   
   }
  
  
  
  1.9.2.2   +16 -0     xml-xalan/java/src/org/apache/xalan/templates/AVTPartSimple.java
  
  Index: AVTPartSimple.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/AVTPartSimple.java,v
  retrieving revision 1.9.2.1
  retrieving revision 1.9.2.2
  diff -u -r1.9.2.1 -r1.9.2.2
  --- AVTPartSimple.java	2001/04/10 18:44:45	1.9.2.1
  +++ AVTPartSimple.java	2001/06/11 20:16:10	1.9.2.2
  @@ -92,6 +92,22 @@
     {
       return m_val;
     }
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    // no-op
  +  }
  +
   
     /**
      * Write the value into the buffer.
  
  
  
  1.12.2.3  +15 -0     xml-xalan/java/src/org/apache/xalan/templates/AVTPartXPath.java
  
  Index: AVTPartXPath.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/AVTPartXPath.java,v
  retrieving revision 1.12.2.2
  retrieving revision 1.12.2.3
  diff -u -r1.12.2.2 -r1.12.2.3
  --- AVTPartXPath.java	2001/05/19 07:05:43	1.12.2.2
  +++ AVTPartXPath.java	2001/06/11 20:16:11	1.12.2.3
  @@ -79,6 +79,21 @@
     private XPath m_xpath;
     
     /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    m_xpath.fixupVariables(vars, globalsSize);
  +  }
  +  
  +  /**
      * Tell if this expression or it's subexpressions can traverse outside 
      * the current subtree.
      * 
  
  
  
  1.13.2.5  +210 -64   xml-xalan/java/src/org/apache/xalan/templates/ElemApplyTemplates.java
  
  Index: ElemApplyTemplates.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemApplyTemplates.java,v
  retrieving revision 1.13.2.4
  retrieving revision 1.13.2.5
  diff -u -r1.13.2.4 -r1.13.2.5
  --- ElemApplyTemplates.java	2001/06/04 07:52:50	1.13.2.4
  +++ ElemApplyTemplates.java	2001/06/11 20:16:12	1.13.2.5
  @@ -79,6 +79,11 @@
   import javax.xml.transform.TransformerException;
   import javax.xml.transform.SourceLocator;
   
  +import org.apache.xml.dtm.DTMManager;
  +
  +// Experemental
  +import org.apache.xml.dtm.ref.ExpandedNameTable;
  +
   /**
    * <meta name="usage" content="advanced"/>
    * Implement xsl:apply-templates.
  @@ -128,6 +133,12 @@
      * @serial
      */
     private boolean m_isDefaultTemplate = false;
  +  
  +//  /**
  +//   * List of namespace/localname IDs, for identification of xsl:with-param to 
  +//   * xsl:params.  Initialized in the compose() method.
  +//   */
  +//  private int[] m_paramIDs;
   
     /**
      * Set if this belongs to a default template,
  @@ -152,6 +163,17 @@
     {
       return Constants.ELEMNAME_APPLY_TEMPLATES;
     }
  +  
  +  /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    super.compose(sroot);
  +  }
   
     /**
      * Return the node name.
  @@ -201,7 +223,7 @@
             transformer.pushMode(m_mode);
           }
         }
  -      transformSelectedNodes(transformer, null);
  +      transformSelectedNodes(transformer);
       }
       finally
       {
  @@ -212,85 +234,209 @@
       }
     }
   
  -  /**
  -   * Return whether or not we need to push default arguments on the stack
  -   *
  -   *
  -   * @return whether or not to push default arguments on the stack
  -   */
  -  public boolean needToPushParams()
  -  {
  -    return true;
  -  }
     
  -
     /**
  -   * Push default arguments on the stack
  -   *
  +   * <meta name="usage" content="advanced"/>
  +   * Perform a query if needed, and call transformNode for each child.
      *
      * @param transformer non-null reference to the the current transform-time state.
  -   * @param xctxt The XPath runtime state for this transformation.
  -   * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
  -   * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
  +   * @param template The owning template context.
      *
  -   * @return The original value of where to start the current search for a variable.
  -   * This value will be used by popParams to restore the value of
  -   * VariableStack.m_searchStart.
  -   *
  -   * @throws TransformerException
  +   * @throws TransformerException Thrown in a variety of circumstances.
      */
  -  public int pushParams(TransformerImpl transformer, XPathContext xctxt)
  -          throws TransformerException
  +  public void transformSelectedNodes(TransformerImpl transformer)
  +            throws TransformerException
     {
  -    if(m_isDefaultTemplate)
  -      return -1;
   
  +    final XPathContext xctxt = transformer.getXPathContext();
  +    final int sourceNode = xctxt.getCurrentNode();
  +    DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt, sourceNode);
       VariableStack vars = xctxt.getVarStack();
  -    int savedSearchStart = vars.getSearchStart();
  +    int nParams = getParamElemCount();
   
  -    if (null != m_paramElems)
  +    try
       {
  -      transformer.pushParams(xctxt, this);
  -    }
  -    else
  -      vars.pushContextMarker();
   
  -    vars.setSearchStart(-1);
  +      //      if (TransformerImpl.S_DEBUG)
  +      //        transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
  +      //                          "test", m_selectExpression,
  +      //                          new org.apache.xpath.objects.XNodeSet(sourceNodes));
  +      final Vector keys = (m_sortElems == null)
  +                          ? null
  +                          : transformer.processSortKeys(this, sourceNode);
  +
  +      // Sort if we need to.
  +      if (null != keys)
  +        sourceNodes = sortNodes(xctxt, keys, sourceNodes);
  +
  +      final ResultTreeHandler rth = transformer.getResultTreeHandler();
  +      ContentHandler chandler = rth.getContentHandler();
  +      final StylesheetRoot sroot = transformer.getStylesheet();
  +      final TemplateList tl = sroot.getTemplateListComposed();
  +      final boolean quiet = transformer.getQuietConflictWarnings();
  +      
  +      xctxt.pushCurrentNode(DTM.NULL);
  +      int[] currentNodes = xctxt.getCurrentNodeStack();
  +      int currentNodePos = xctxt.getCurrentNodeFirstFree() - 1;
  +      
  +      xctxt.pushCurrentExpressionNode(DTM.NULL);
  +      int[] currentExpressionNodes = xctxt.getCurrentExpressionNodeStack();
  +      int currentExpressionNodePos = xctxt.getCurrentExpressionNodesFirstFree() - 1;
  +
  +      xctxt.pushSAXLocatorNull();
  +      xctxt.pushContextNodeList(sourceNodes);
  +      transformer.pushElemTemplateElement(null);
  +      // pushParams(transformer, xctxt);
  +
  +      // Should be able to get this from the iterator but there must be a bug.
  +      DTM dtm = xctxt.getDTM(sourceNode);
  +      int docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
  +      
  +      int argsFrame = -1;
  +      if(nParams > 0)
  +      {
  +        // This code will create a section on the stack that is all the 
  +        // evaluated arguments.  These will be copied into the real params 
  +        // section of each called template.
  +        int thisframe = vars.getStackFrame();
  +        argsFrame = vars.link(nParams);
  +        vars.setStackFrame(thisframe);
  +        
  +        for (int i = 0; i < nParams; i++) 
  +        {
  +          ElemWithParam ewp = m_paramElems[i];
  +          XObject obj = ewp.getValue(transformer, sourceNode);
  +          
  +          vars.setLocalVariable(i, obj, argsFrame);
  +        }
  +        vars.setStackFrame(argsFrame);
  +      }
  +      
  +      
  +      int child;
  +      while (DTM.NULL != (child = sourceNodes.nextNode()))
  +      {
  +        currentNodes[currentNodePos] = child;
  +        currentExpressionNodes[currentExpressionNodePos] = child;
   
  -    return savedSearchStart;
  -  }
  +        if((child & DTMManager.IDENT_DTM_DEFAULT) != docID)
  +        {
  +          dtm = xctxt.getDTM(child);
  +          docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
  +        }
  +        
  +        final int exNodeType = dtm.getExpandedTypeID(child);
  +        final int nodeType = (exNodeType >> ExpandedNameTable.ROTAMOUNT_TYPE);
  +
  +        final QName mode = transformer.getMode();
  +
  +        ElemTemplate template = tl.getTemplateFast(xctxt, child, exNodeType, mode, 
  +                                      -1, quiet, dtm);
  +
  +        // If that didn't locate a node, fall back to a default template rule.
  +        // See http://www.w3.org/TR/xslt#built-in-rule.
  +        if (null == template)
  +        {
  +          switch (nodeType)
  +          {
  +          case DTM.DOCUMENT_FRAGMENT_NODE :
  +          case DTM.ELEMENT_NODE :
  +            template = sroot.getDefaultRule();
  +            // %OPT% direct faster?
  +            break;
  +          case DTM.ATTRIBUTE_NODE :
  +          case DTM.CDATA_SECTION_NODE :
  +          case DTM.TEXT_NODE :
  +            if(rth.m_elemIsPending || rth.m_docPending)
  +              rth.flushPending(true);
  +            dtm.dispatchCharactersEvents(child, chandler, false);
  +            continue;
  +          case DTM.DOCUMENT_NODE :
  +            template = sroot.getDefaultRootRule();
  +            break;
  +          default :
  +
  +            // No default rules for processing instructions and the like.
  +            continue;
  +          }
  +        }
  +        
  +        transformer.pushPairCurrentMatched(template, child);
   
  -  /**
  -   * Re-mark the params as params.
  -   *
  -   * NEEDSDOC @param xctxt
  -   */
  -  public void reMarkParams(XPathContext xctxt)
  -  {
  -    if(m_isDefaultTemplate)
  -      return;
  +        if(template.m_frameSize > 0)
  +        {
  +          vars.link(template.m_frameSize);
  +          if(nParams > 0 && template.m_inArgsSize > 0)
  +          {
  +            int paramIndex = 0;
  +            for (ElemTemplateElement elem = template.getFirstChildElem(); 
  +                 null != elem; elem = elem.getNextSiblingElem()) 
  +            {
  +              if(Constants.ELEMNAME_PARAMVARIABLE == elem.getXSLToken())
  +              {
  +                ElemParam ep = (ElemParam)elem;
  +                int i;
  +                for (i = 0; i < nParams; i++) 
  +                {
  +                  ElemWithParam ewp = m_paramElems[i];
  +                  if(ewp.m_qnameID == ep.m_qnameID)
  +                  {
  +                    XObject obj = vars.getLocalVariable(i, argsFrame);
  +                    vars.setLocalVariable(paramIndex, obj);
  +                    break;
  +                  }
  +                }
  +                if(i == nParams)
  +                  vars.setLocalVariable(paramIndex, null);
  +              }
  +              else
  +                break;
  +              paramIndex++;
  +            }
  +            
  +          }
  +        }
   
  -    VariableStack vars = xctxt.getVarStack();
  +        // if (check)
  +        //  guard.push(this, child);
   
  -    vars.remarkParams();
  +        // Fire a trace event for the template.
  +        if (TransformerImpl.S_DEBUG)
  +          transformer.getTraceManager().fireTraceEvent(template);
  +
  +        // And execute the child templates.
  +        // Loop through the children of the template, calling execute on 
  +        // each of them.
  +        for (ElemTemplateElement t = template.m_firstChild; 
  +             t != null; t = t.m_nextSibling)
  +        {
  +          xctxt.setSAXLocator(t);
  +          transformer.setCurrentElement(t);
  +          t.execute(transformer);
  +        }
  +        
  +        if(template.m_frameSize > 0)
  +          vars.unlink();
  +          
  +        transformer.popCurrentMatched();
  +        
  +      } // end while (DTM.NULL != (child = sourceNodes.nextNode()))
  +    }
  +    catch (SAXException se)
  +    {
  +      transformer.getErrorListener().fatalError(new TransformerException(se));
  +    }
  +    finally
  +    {
  +      if(nParams > 0)
  +        vars.unlink();
  +      xctxt.popSAXLocator();
  +      xctxt.popContextNodeList();
  +      transformer.popElemTemplateElement();
  +      xctxt.popCurrentExpressionNode();
  +      xctxt.popCurrentNode();
  +      sourceNodes.detach();
  +    }
     }
   
  -  /**
  -   * Pop the stack of default arguments after we're done with them
  -   *
  -   *
  -   * @param xctxt The XPath runtime state for this transformation.
  -   * @param savedSearchStart Value to restore VariableStack.m_searchStart
  -   * to. This is used to set where to start the current search for a variable.
  -   */
  -  public void popParams(XPathContext xctxt, int savedSearchStart)
  -  {
  -    if(m_isDefaultTemplate)
  -      return;
  -
  -    VariableStack vars = xctxt.getVarStack();
  -
  -    vars.popCurrentContext();
  -    vars.setSearchStart(savedSearchStart);
  -  }
   }
  
  
  
  1.17.2.2  +108 -22   xml-xalan/java/src/org/apache/xalan/templates/ElemCallTemplate.java
  
  Index: ElemCallTemplate.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemCallTemplate.java,v
  retrieving revision 1.17.2.1
  retrieving revision 1.17.2.2
  diff -u -r1.17.2.1 -r1.17.2.2
  --- ElemCallTemplate.java	2001/04/10 18:44:46	1.17.2.1
  +++ ElemCallTemplate.java	2001/06/11 20:16:12	1.17.2.2
  @@ -67,9 +67,9 @@
   import org.apache.xalan.res.XSLTErrorResources;
   import org.apache.xpath.VariableStack;
   import org.apache.xalan.transformer.TransformerImpl;
  -
   import javax.xml.transform.SourceLocator;
   import javax.xml.transform.TransformerException;
  +import org.apache.xpath.objects.XObject;
   
   /**
    * <meta name="usage" content="advanced"/>
  @@ -120,7 +120,7 @@
      * The template which is named by QName.
      * @serial
      */
  -  private ElemTemplateElement m_template = null;
  +  private ElemTemplate m_template = null;
   
     /**
      * Get an int constant identifying the type of element.
  @@ -149,15 +149,69 @@
      * values that may be based on some other property that
      * depends on recomposition.
      */
  -  public void compose() throws TransformerException
  +  public void compose(StylesheetRoot sroot) throws TransformerException
     {
  -    super.compose();
  +    super.compose(sroot);
  +    
  +    // Call compose on each param no matter if this is apply-templates 
  +    // or call templates.
  +    int length = getParamElemCount();
  +    for (int i = 0; i < length; i++) 
  +    {
  +      ElemWithParam ewp = getParamElem(i);
  +      ewp.compose(sroot);
  +    }
  +    
       if ((null != m_templateName) && (null == m_template))
       {
         m_template =
           this.getStylesheetRoot().getTemplateComposed(m_templateName);
  +        
  +      if(null == m_template)
  +        return; // %REVIEW% error?
  +    
  +      length = getParamElemCount();
  +      for (int i = 0; i < length; i++) 
  +      {
  +        ElemWithParam ewp = getParamElem(i);
  +        ewp.m_index = -1;
  +        // Find the position of the param in the template being called, 
  +        // and set the index of the param slot.
  +        int etePos = 0;
  +        for (ElemTemplateElement ete = m_template.getFirstChildElem(); 
  +             null != ete; ete = ete.getNextSiblingElem()) 
  +        {
  +          if(ete.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE)
  +          {
  +            ElemParam ep = (ElemParam)ete;
  +            if(ep.getName().equals(ewp.getName()))
  +            {
  +              ewp.m_index = etePos;
  +            }
  +          }
  +          else
  +            break;
  +          etePos++;
  +        }
  +        
  +      }
       }
     }
  +  
  +  /**
  +   * This after the template's children have been composed.
  +   */
  +  public void endCompose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    int length = getParamElemCount();
  +    for (int i = 0; i < length; i++) 
  +    {
  +      ElemWithParam ewp = getParamElem(i);
  +      ewp.endCompose(sroot);
  +    }    
  +    
  +    super.endCompose(sroot);
  +  }
   
     /**
      * Invoke a named template.
  @@ -181,16 +235,39 @@
       {
         XPathContext xctxt = transformer.getXPathContext();
         VariableStack vars = xctxt.getVarStack();
  -
  -      int savedSearchStart = vars.getSearchStart();
   
  -      if (null != m_paramElems)
  -        transformer.pushParams(xctxt, this);
  -      else
  -        vars.pushContextMarker();
  +      int thisframe = vars.getStackFrame();
  +      int nextFrame = vars.link(m_template.m_frameSize);
         
  -      vars.setSearchStart(-1);
  -
  +      // We have to clear the section of the stack frame that has params 
  +      // so that the default param evaluation will work correctly.
  +      if(m_template.m_inArgsSize > 0)
  +      {
  +        vars.clearLocalSlots(0, m_template.m_inArgsSize);
  +      
  +        if(null != m_paramElems)
  +        {
  +          int currentNode = xctxt.getCurrentNode();
  +          vars.setStackFrame(thisframe);
  +          int size = m_paramElems.length;
  +          
  +          for (int i = 0; i < size; i++) 
  +          {
  +            ElemWithParam ewp = m_paramElems[i];
  +            if(ewp.m_index >= 0)
  +            {
  +              XObject obj = ewp.getValue(transformer, currentNode);
  +              
  +              // Note here that the index for ElemWithParam must have been 
  +              // statically made relative to the xsl:template being called, 
  +              // NOT this xsl:template.
  +              vars.setLocalVariable(ewp.m_index, obj, nextFrame);
  +            }
  +          }
  +          vars.setStackFrame(nextFrame);
  +        }
  +      }
  +      
         SourceLocator savedLocator = xctxt.getSAXLocator();
   
         try
  @@ -205,8 +282,7 @@
         {
           transformer.popElemTemplateElement();
           xctxt.setSAXLocator(savedLocator);
  -        vars.popCurrentContext();
  -        vars.setSearchStart(savedSearchStart);
  +        vars.unlink();
         }
       }
       else
  @@ -215,10 +291,10 @@
                                       new Object[]{ m_templateName });  //"Could not find template named: '"+templateName+"'");
       }
     }
  -
  +  
     /** Vector of xsl:param elements associated with this element. 
      *  @serial */
  -  protected Vector m_paramElems = null;
  +  protected ElemWithParam[] m_paramElems = null;
   
     /**
      * Get the count xsl:param elements associated with this element.
  @@ -226,7 +302,7 @@
      */
     public int getParamElemCount()
     {
  -    return (m_paramElems == null) ? 0 : m_paramElems.size();
  +    return (m_paramElems == null) ? 0 : m_paramElems.length;
     }
   
     /**
  @@ -238,7 +314,7 @@
      */
     public ElemWithParam getParamElem(int i)
     {
  -    return (ElemWithParam) m_paramElems.elementAt(i);
  +    return m_paramElems[i];
     }
   
     /**
  @@ -248,11 +324,21 @@
      */
     public void setParamElem(ElemWithParam ParamElem)
     {
  -
       if (null == m_paramElems)
  -      m_paramElems = new Vector();
  -
  -    m_paramElems.addElement(ParamElem);
  +    {
  +      m_paramElems = new ElemWithParam[1];
  +      m_paramElems[0] = ParamElem;
  +    }
  +    else
  +    {
  +      // Expensive 1 at a time growth, but this is done at build time, so 
  +      // I think it's OK.
  +      int length = m_paramElems.length;
  +      ElemWithParam[] ewp = new ElemWithParam[length + 1];
  +      System.arraycopy(m_paramElems, 0, ewp, 0, length);
  +      m_paramElems = ewp;
  +      ewp[length] = ParamElem;
  +    }
     }
   
     /**
  
  
  
  1.9.2.4   +23 -16    xml-xalan/java/src/org/apache/xalan/templates/ElemChoose.java
  
  Index: ElemChoose.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemChoose.java,v
  retrieving revision 1.9.2.3
  retrieving revision 1.9.2.4
  diff -u -r1.9.2.3 -r1.9.2.4
  --- ElemChoose.java	2001/06/08 19:01:57	1.9.2.3
  +++ ElemChoose.java	2001/06/11 20:16:13	1.9.2.4
  @@ -96,7 +96,7 @@
     /**
      * Return the node name.
      *
  -   * @return The element's name 
  +   * @return The element's name
      */
     public String getNodeName()
     {
  @@ -110,7 +110,7 @@
     public ElemChoose(){}
   
     /**
  -   * Execute the xsl:choose transformation. 
  +   * Execute the xsl:choose transformation.
      *
      *
      * @param transformer non-null reference to the the current transform-time state.
  @@ -119,9 +119,7 @@
      *
      * @throws TransformerException
      */
  -  public void execute(
  -          TransformerImpl transformer)
  -            throws TransformerException
  +  public void execute(TransformerImpl transformer) throws TransformerException
     {
   
       if (TransformerImpl.S_DEBUG)
  @@ -143,23 +141,32 @@
           // must be xsl:when
           XPathContext xctxt = transformer.getXPathContext();
           int sourceNode = xctxt.getCurrentNode();
  -        XObject test = when.getTest().execute(transformer.getXPathContext(),
  -                                              sourceNode, when);
   
           if (TransformerImpl.S_DEBUG)
  -          transformer.getTraceManager().fireSelectedEvent(sourceNode, when,
  -                  "test", when.getTest(), test);
  +        {
  +          XObject test = when.getTest().execute(xctxt, sourceNode, when);
   
  -        if ((null != test) && test.bool())
  +          if (TransformerImpl.S_DEBUG)
  +            transformer.getTraceManager().fireSelectedEvent(sourceNode, when,
  +                    "test", when.getTest(), test);
  +
  +          if (test.bool())
  +          {
  +            transformer.executeChildTemplates(when, true);
  +
  +            return;
  +          }
  +
  +          if (TransformerImpl.S_DEBUG)
  +            transformer.getTraceManager().fireSelectedEvent(sourceNode, when,
  +                    "endTest", when.getTest(), test);
  +        }
  +        else if (when.getTest().bool(xctxt, sourceNode, when))
           {
             transformer.executeChildTemplates(when, true);
   
             return;
           }
  -				
  -				if (TransformerImpl.S_DEBUG)
  -          transformer.getTraceManager().fireSelectedEvent(sourceNode, when,
  -                  "endTest", when.getTest(), test);
         }
         else if (Constants.ELEMNAME_OTHERWISE == type)
         {
  @@ -173,8 +180,8 @@
       }
   
       if (!found)
  -      transformer.getMsgMgr().error(this,
  -        XSLTErrorResources.ER_CHOOSE_REQUIRES_WHEN);
  +      transformer.getMsgMgr().error(
  +        this, XSLTErrorResources.ER_CHOOSE_REQUIRES_WHEN);
     }
   
     /**
  
  
  
  1.12.2.4  +1 -1      xml-xalan/java/src/org/apache/xalan/templates/ElemCopy.java
  
  Index: ElemCopy.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemCopy.java,v
  retrieving revision 1.12.2.3
  retrieving revision 1.12.2.4
  diff -u -r1.12.2.3 -r1.12.2.4
  --- ElemCopy.java	2001/06/03 03:24:21	1.12.2.3
  +++ ElemCopy.java	2001/06/11 20:16:13	1.12.2.4
  @@ -140,7 +140,7 @@
       try
       {
         int sourceNode = xctxt.getCurrentNode();
  -                        xctxt.pushCurrentNode(sourceNode);
  +      xctxt.pushCurrentNode(sourceNode);
         DTM dtm = xctxt.getDTM(sourceNode);
         short nodeType = dtm.getNodeType(sourceNode);
   
  
  
  
  1.10.2.5  +14 -0     xml-xalan/java/src/org/apache/xalan/templates/ElemCopyOf.java
  
  Index: ElemCopyOf.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemCopyOf.java,v
  retrieving revision 1.10.2.4
  retrieving revision 1.10.2.5
  diff -u -r1.10.2.4 -r1.10.2.5
  --- ElemCopyOf.java	2001/06/08 19:01:58	1.10.2.4
  +++ ElemCopyOf.java	2001/06/11 20:16:13	1.10.2.5
  @@ -114,6 +114,20 @@
     {
       return m_selectExpression;
     }
  +  
  +  /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    super.compose(sroot);
  +    
  +    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  +    m_selectExpression.fixupVariables(cstate.getVariableNames(), cstate.getGlobalsSize());
  +  }
   
     /**
      * Get an int constant identifying the type of element.
  
  
  
  1.18.2.3  +19 -0     xml-xalan/java/src/org/apache/xalan/templates/ElemElement.java
  
  Index: ElemElement.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemElement.java,v
  retrieving revision 1.18.2.2
  retrieving revision 1.18.2.3
  diff -u -r1.18.2.2 -r1.18.2.3
  --- ElemElement.java	2001/05/06 02:09:27	1.18.2.2
  +++ ElemElement.java	2001/06/11 20:16:14	1.18.2.3
  @@ -156,6 +156,25 @@
     {
       return m_namespace_avt;
     }
  +  
  +  /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    super.compose(sroot);
  +    
  +    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  +    java.util.Vector vnames = cstate.getVariableNames();
  +    if(null != m_name_avt)
  +      m_name_avt.fixupVariables(vnames, cstate.getGlobalsSize());
  +    if(null != m_namespace_avt)
  +      m_namespace_avt.fixupVariables(vnames, cstate.getGlobalsSize());
  +  }
  +
   
     /**
      * Get an int constant identifying the type of element.
  
  
  
  1.24.2.4  +2 -2      xml-xalan/java/src/org/apache/xalan/templates/ElemExtensionCall.java
  
  Index: ElemExtensionCall.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemExtensionCall.java,v
  retrieving revision 1.24.2.3
  retrieving revision 1.24.2.4
  diff -u -r1.24.2.3 -r1.24.2.4
  --- ElemExtensionCall.java	2001/05/17 05:38:45	1.24.2.3
  +++ ElemExtensionCall.java	2001/06/11 20:16:14	1.24.2.4
  @@ -142,10 +142,10 @@
      * values that may be based on some other property that
      * depends on recomposition.
      */
  -  public void compose() throws TransformerException
  +  public void compose(StylesheetRoot sroot) throws TransformerException
     {
   
  -    super.compose();
  +    super.compose(sroot);
       m_extns = this.getNamespace();
   
       StylesheetRoot stylesheet = this.getStylesheetRoot();
  
  
  
  1.20.2.10 +82 -257   xml-xalan/java/src/org/apache/xalan/templates/ElemForEach.java
  
  Index: ElemForEach.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemForEach.java,v
  retrieving revision 1.20.2.9
  retrieving revision 1.20.2.10
  diff -u -r1.20.2.9 -r1.20.2.10
  --- ElemForEach.java	2001/06/08 19:01:59	1.20.2.9
  +++ ElemForEach.java	2001/06/11 20:16:14	1.20.2.10
  @@ -116,15 +116,15 @@
      * @serial
      */
     protected Expression m_selectExpression = null;
  -	
  -	 /**
  +        
  +         /**
      * Set the "select" attribute.
      *
      * @param xpath The XPath expression for the "select" attribute.
      */
     public void setSelect(XPath xpath)
     {
  -		m_selectExpression = xpath.getExpression();
  +                m_selectExpression = xpath.getExpression();
     }
   
     /**
  @@ -136,25 +136,49 @@
     {
       return m_selectExpression;
     }
  -
  +  
     /**
      * This function is called after everything else has been
      * recomposed, and allows the template to set remaining
      * values that may be based on some other property that
      * depends on recomposition.
  -   *
  -   * @throws TransformerException
      */
  -  public void compose() throws TransformerException
  +  public void compose(StylesheetRoot sroot) throws TransformerException
     {
  -
  -    if (null == m_selectExpression)
  +    super.compose(sroot);
  +    int length = getSortElemCount();
  +    for (int i = 0; i < length; i++) 
  +    {
  +      getSortElem(i).compose(sroot);
  +    }
  +    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
  +    if(null != m_selectExpression)
  +      m_selectExpression.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
  +    else
       {
  -			m_selectExpression =
  +                        m_selectExpression =
           getStylesheetRoot().m_selectDefault.getExpression();
       }
     }
   
  +//  /**
  +//   * This function is called after everything else has been
  +//   * recomposed, and allows the template to set remaining
  +//   * values that may be based on some other property that
  +//   * depends on recomposition.
  +//   *
  +//   * @throws TransformerException
  +//   */
  +//  public void compose() throws TransformerException
  +//  {
  +//
  +//    if (null == m_selectExpression)
  +//    {
  +//      m_selectExpression =
  +//        getStylesheetRoot().m_selectDefault.getExpression();
  +//    }
  +//  }
  +
     /**
      * Vector containing the xsl:sort elements associated with this element.
      *  @serial         
  @@ -234,7 +258,7 @@
         if (TransformerImpl.S_DEBUG)
           transformer.getTraceManager().fireTraceEvent(this);
   
  -      transformSelectedNodes(transformer, this);
  +      transformSelectedNodes(transformer);
       }
       finally
       {
  @@ -290,67 +314,6 @@
     }
   
     /**
  -   * Return whether or not default parameters need to be pushed into stack
  -   *
  -   *
  -   * @return False, no need to push parameters here.
  -   */
  -  public boolean needToPushParams()
  -  {
  -    return false;
  -  }
  -
  -  /**
  -   * Push default parameters into the stack
  -   *
  -   *
  -   * @param transformer non-null reference to the the current transform-time state.
  -   * @param xctxt The XPath runtime state.
  -   * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
  -   * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
  -   *
  -   * @return -1, this return will not be used by ElemForEach.
  -   * It is just there because ElemApplyTemplates which derives
  -   * from this needs to that value to be saved.
  -   *
  -   * @throws TransformerException
  -   */
  -  public int pushParams(TransformerImpl transformer, XPathContext xctxt)
  -          throws TransformerException
  -  {
  -
  -    VariableStack vars = xctxt.getVarStack();
  -
  -    vars.pushElemFrame();
  -
  -    return -1;
  -  }
  -
  -  /**
  -   * Re-mark the params as params.
  -   *
  -   * NEEDSDOC @param xctxt
  -   */
  -  public void reMarkParams(XPathContext xctxt){}
  -
  -  /**
  -   * Pop Default parameters from the stack
  -   *
  -   *
  -   * @param xctxt The XPath runtime state.
  -   * @param savedSearchStart This param will not be used by ElemForEach.
  -   * It is just there because ElemApplyTemplates which derives
  -   * from this needs to restore that value.
  -   */
  -  public void popParams(XPathContext xctxt, int savedSearchStart)
  -  {
  -
  -    VariableStack vars = xctxt.getVarStack();
  -
  -    vars.popElemFrame();
  -  }
  -
  -  /**
      * <meta name="usage" content="advanced"/>
      * Perform a query if needed, and call transformNode for each child.
      *
  @@ -359,8 +322,7 @@
      *
      * @throws TransformerException Thrown in a variety of circumstances.
      */
  -  public void transformSelectedNodes(
  -          TransformerImpl transformer, ElemTemplateElement template)
  +  public void transformSelectedNodes(TransformerImpl transformer)
               throws TransformerException
     {
   
  @@ -369,26 +331,22 @@
       DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt, sourceNode);
   
       try
  -		{
  +    {
   
  -			if (TransformerImpl.S_DEBUG)
  -				transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
  -																												"test", new XPath(m_selectExpression),
  -																												new org.apache.xpath.objects.XNodeSet(sourceNodes));
  -			final Vector keys = (m_sortElems == null)
  -													? null
  -														: transformer.processSortKeys(this, sourceNode);
  +      if (TransformerImpl.S_DEBUG)
  +              transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
  +              "test", new XPath(m_selectExpression),
  +                                                                                                                                                                                                              new org.apache.xpath.objects.XNodeSet(sourceNodes));
  +      final Vector keys = (m_sortElems == null)
  +            ? null
  +            : transformer.processSortKeys(this, sourceNode);
   
  -			// Sort if we need to.
  +      // Sort if we need to.
         if (null != keys)
           sourceNodes = sortNodes(xctxt, keys, sourceNodes);
   
         final ResultTreeHandler rth = transformer.getResultTreeHandler();
         ContentHandler chandler = rth.getContentHandler();
  -      final StylesheetRoot sroot = transformer.getStylesheet();
  -      final TemplateList tl = sroot.getTemplateListComposed();
  -      final boolean needToFindTemplate = (null == template);
  -      final boolean quiet = transformer.getQuietConflictWarnings();
         
         xctxt.pushCurrentNode(DTM.NULL);
         int[] currentNodes = xctxt.getCurrentNodeStack();
  @@ -398,185 +356,52 @@
         int[] currentExpressionNodes = xctxt.getCurrentExpressionNodeStack();
         int currentExpressionNodePos = xctxt.getCurrentExpressionNodesFirstFree() - 1;
   
  -      // StylesheetComposed stylesheet = getStylesheetComposed();
  -      boolean didSetVars = false;
  -      // boolean check = false;
  -      int savedSearchStart = 0;
  -
  -      try
  +      xctxt.pushSAXLocatorNull();
  +      xctxt.pushContextNodeList(sourceNodes);
  +      transformer.pushElemTemplateElement(null);
  +      // pushParams(transformer, xctxt);
  +
  +      // Should be able to get this from the iterator but there must be a bug.
  +      DTM dtm = xctxt.getDTM(sourceNode);
  +      int docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
  +      
  +      int child;
  +      while (DTM.NULL != (child = sourceNodes.nextNode()))
         {
  -        // Should be able to get this from the iterator but there must be a bug.
  -        DTM dtm = xctxt.getDTM(sourceNode);
  -        int docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
  -        
  -        int child;
  -        while (DTM.NULL != (child = sourceNodes.nextNode()))
  -        {
  -          currentNodes[currentNodePos] = child;
  -          currentExpressionNodes[currentExpressionNodePos] = child;
  +        currentNodes[currentNodePos] = child;
  +        currentExpressionNodes[currentExpressionNodePos] = child;
   
  -          if((child & DTMManager.IDENT_DTM_DEFAULT) != docID)
  -          {
  -            dtm = xctxt.getDTM(child);
  -            docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
  -          }
  -          
  -          final int exNodeType = dtm.getExpandedTypeID(child);
  -          final int nodeType = (exNodeType >> ExpandedNameTable.ROTAMOUNT_TYPE);
  -
  -          if (needToFindTemplate)
  -          {
  -            final QName mode = transformer.getMode();
  -
  -            template = tl.getTemplateFast(xctxt, child, exNodeType, mode, 
  -                                          -1, quiet, dtm);
  -
  -            // If that didn't locate a node, fall back to a default template rule.
  -            // See http://www.w3.org/TR/xslt#built-in-rule.
  -            if (null == template)
  -            {
  -              switch (nodeType)
  -              {
  -              case DTM.DOCUMENT_FRAGMENT_NODE :
  -              case DTM.ELEMENT_NODE :
  -                template = sroot.getDefaultRule();
  -                break;
  -              case DTM.ATTRIBUTE_NODE :
  -              case DTM.CDATA_SECTION_NODE :
  -              case DTM.TEXT_NODE :
  -                if(rth.m_elemIsPending || rth.m_docPending)
  -                  rth.flushPending(true);
  -                dtm.dispatchCharactersEvents(child, chandler, false);
  -                continue;
  -              case DTM.DOCUMENT_NODE :
  -                template = sroot.getDefaultRootRule();
  -                break;
  -              default :
  -
  -                // No default rules for processing instructions and the like.
  -                continue;
  -              }
  -            }
  -          }
  -
  -          if (!didSetVars)
  -          {
  -            didSetVars = true;
  -            // check = (transformer.getStackGuard().m_recursionLimit > -1);
  -
  -            xctxt.pushSAXLocatorNull();
  -            xctxt.pushContextNodeList(sourceNodes);
  -            transformer.pushElemTemplateElement(null);
  -            savedSearchStart = pushParams(transformer, xctxt);
  -          }
  -
  -          // If we are processing the default text rule, then just clone 
  -          // the value directly to the result tree.
  -          try
  -          {
  -            if (needToFindTemplate)
  -              transformer.pushPairCurrentMatched(template, child);
  -
  -            // if (check)
  -            //  guard.push(this, child);
  -
  -            // Fire a trace event for the template.
  -            if (TransformerImpl.S_DEBUG)
  -              transformer.getTraceManager().fireTraceEvent(template);
  -
  -            // And execute the child templates.
  -            // Loop through the children of the template, calling execute on 
  -            // each of them.
  -            for (ElemTemplateElement t = template.m_firstChild; 
  -                 t != null; t = t.m_nextSibling)
  -            {
  -              xctxt.setSAXLocator(t);
  -              transformer.setCurrentElement(t);
  -
  -              switch (t.getXSLToken())
  -              {
  -              case Constants.ELEMNAME_COPY :
  -              
  -                if ((DTM.DOCUMENT_NODE != nodeType)
  -                        && (DTM.DOCUMENT_FRAGMENT_NODE != nodeType))
  -                {
  -                  // TODO: Process the use-attribute-sets stuff
  -
  -                  if (DTM.ELEMENT_NODE == nodeType)
  -                  {
  -                    String ns = dtm.getNamespaceURI(child);
  -                    String localName = dtm.getLocalName(child);
  -                    String qname = dtm.getNodeNameX(child);
  -          
  -                    rth.startElement(ns, localName, qname, null);
  -
  -                    if(null != ((ElemUse)t).getUseAttributeSets())
  -                      ((ElemUse)t).applyAttrSets(transformer, sroot);
  -                      
  -                    rth.processNSDecls(child, nodeType, dtm);
  -                    transformer.executeChildTemplates(t, true);
  -
  -                    rth.endElement(ns, localName, qname);
  -                  }
  -                  else
  -                  {
  -                    ClonerToResultTree.cloneToResultTree(child, nodeType, 
  -                                                         dtm, rth, false);
  -                    if (TransformerImpl.S_DEBUG)
  -                      transformer.getTraceManager().fireTraceEvent(t);
  -                  }
  -                }
  -                else
  -                {
  -                  if (TransformerImpl.S_DEBUG)
  -                    transformer.getTraceManager().fireTraceEvent(t);
  -
  -                  // super.execute(transformer);
  -                  transformer.executeChildTemplates(t, true);
  -                }
  -                break;
  -              default :
  -                t.execute(transformer);
  -              }
  -            }
  -            if(savedSearchStart > 0)
  -              reMarkParams(xctxt);
  -          }
  -          finally
  -          {
  -            if (needToFindTemplate)
  -              transformer.popCurrentMatched();
  -
  -            // if (check)
  -            //  guard.pop();
  -          }
  -        }
  -				// fire end select event 
  -				if (TransformerImpl.S_DEBUG)
  -					transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
  -																												"endTest", new XPath(m_selectExpression),
  -																												new org.apache.xpath.objects.XNodeSet(sourceNodes));			
  -      }
  -      finally
  -      {
  -        if (didSetVars)
  +        if((child & DTMManager.IDENT_DTM_DEFAULT) != docID)
           {
  -          xctxt.popSAXLocator();
  -          xctxt.popContextNodeList();
  -          transformer.popElemTemplateElement();
  -          popParams(xctxt, savedSearchStart);
  +          dtm = xctxt.getDTM(child);
  +          docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
           }
  +        
  +        final int exNodeType = dtm.getExpandedTypeID(child);
  +        final int nodeType = (exNodeType >> ExpandedNameTable.ROTAMOUNT_TYPE);
  +
   
  -        // if(null != sourceNodes)
  -        //  sourceNodes.detach();                
  +        // Fire a trace event for the template.
  +        if (TransformerImpl.S_DEBUG)
  +          transformer.getTraceManager().fireTraceEvent(this);
  +
  +        // And execute the child templates.
  +        // Loop through the children of the template, calling execute on 
  +        // each of them.
  +        for (ElemTemplateElement t = this.m_firstChild; 
  +             t != null; t = t.m_nextSibling)
  +        {
  +          xctxt.setSAXLocator(t);
  +          transformer.setCurrentElement(t);
  +          t.execute(transformer);
  +        }
         }
       }
  -    catch (SAXException se)
  -    {
  -      transformer.getErrorListener().fatalError(new TransformerException(se));
  -    }
       finally
       {
  +      xctxt.popSAXLocator();
  +      xctxt.popContextNodeList();
  +      transformer.popElemTemplateElement();
         xctxt.popCurrentExpressionNode();
         xctxt.popCurrentNode();
         sourceNodes.detach();
  
  
  
  1.9.2.3   +40 -13    xml-xalan/java/src/org/apache/xalan/templates/ElemIf.java
  
  Index: ElemIf.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemIf.java,v
  retrieving revision 1.9.2.2
  retrieving revision 1.9.2.3
  diff -u -r1.9.2.2 -r1.9.2.3
  --- ElemIf.java	2001/06/08 19:01:59	1.9.2.2
  +++ ElemIf.java	2001/06/11 20:16:15	1.9.2.3
  @@ -106,7 +106,7 @@
      * Get the "test" attribute.
      * The xsl:if element must have a test attribute, which specifies an expression.
      *
  -   * @return the "test" attribute for this element. 
  +   * @return the "test" attribute for this element.
      */
     public XPath getTest()
     {
  @@ -114,6 +114,27 @@
     }
   
     /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   *
  +   * NEEDSDOC @param sroot
  +   *
  +   * @throws TransformerException
  +   */
  +  public void compose(StylesheetRoot sroot) throws TransformerException
  +  {
  +
  +    super.compose(sroot);
  +
  +    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
  +
  +    if (null != m_test)
  +      m_test.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
  +  }
  +
  +  /**
      * Get an int constant identifying the type of element.
      * @see org.apache.xalan.templates.Constants
      *
  @@ -147,29 +168,35 @@
      *
      * @throws TransformerException
      */
  -  public void execute(
  -          TransformerImpl transformer)
  -            throws TransformerException
  +  public void execute(TransformerImpl transformer) throws TransformerException
     {
   
       if (TransformerImpl.S_DEBUG)
         transformer.getTraceManager().fireTraceEvent(this);
   
       XPathContext xctxt = transformer.getXPathContext();
  -    
       int sourceNode = xctxt.getCurrentNode();
  -    XObject test = m_test.execute(xctxt, sourceNode, this);
  +
       if (TransformerImpl.S_DEBUG)
  -      transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
  -              "test", m_test, test);
  +    {
  +      XObject test = m_test.execute(xctxt, sourceNode, this);
   
  -    if (test.bool())
  +      if (TransformerImpl.S_DEBUG)
  +        transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
  +                "test", m_test, test);
  +
  +      if (test.bool())
  +      {
  +        transformer.executeChildTemplates(this, true);
  +      }
  +
  +      if (TransformerImpl.S_DEBUG)
  +        transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
  +                "endTest", m_test, test);
  +    }
  +    else if (m_test.bool(xctxt, sourceNode, this))
       {
         transformer.executeChildTemplates(this, true);
       }
  -		
  -		if (TransformerImpl.S_DEBUG)
  -      transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
  -              "endTest", m_test, test);
     }
   }
  
  
  
  1.25.2.2  +23 -0     xml-xalan/java/src/org/apache/xalan/templates/ElemLiteralResult.java
  
  Index: ElemLiteralResult.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemLiteralResult.java,v
  retrieving revision 1.25.2.1
  retrieving revision 1.25.2.2
  diff -u -r1.25.2.1 -r1.25.2.2
  --- ElemLiteralResult.java	2001/04/10 18:44:48	1.25.2.1
  +++ ElemLiteralResult.java	2001/06/11 20:16:16	1.25.2.2
  @@ -121,7 +121,30 @@
     {
       return isLiteralResultAsStylesheet;
     }
  +  
  +  /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    super.compose(sroot);
  +    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  +    java.util.Vector vnames = cstate.getVariableNames();
  +    if (null != m_avts)
  +    {
  +      int nAttrs = m_avts.size();
   
  +      for (int i = (nAttrs - 1); i >= 0; i--)
  +      {
  +        AVT avt = (AVT) m_avts.elementAt(i);
  +        avt.fixupVariables(vnames, cstate.getGlobalsSize());
  +      } 
  +    }   
  +  }
  +  
     /**
      * The created element node will have the attribute nodes
      * that were present on the element node in the stylesheet tree,
  
  
  
  1.18.2.3  +30 -0     xml-xalan/java/src/org/apache/xalan/templates/ElemNumber.java
  
  Index: ElemNumber.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemNumber.java,v
  retrieving revision 1.18.2.2
  retrieving revision 1.18.2.3
  diff -u -r1.18.2.2 -r1.18.2.3
  --- ElemNumber.java	2001/05/06 02:09:28	1.18.2.2
  +++ ElemNumber.java	2001/06/11 20:16:16	1.18.2.3
  @@ -477,6 +477,36 @@
      * @see TransformerImpl#int2alphaCount
      */
     private static char[] m_alphaCountTable = null;
  +  
  +  /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    super.compose(sroot);
  +    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  +    java.util.Vector vnames = cstate.getVariableNames();
  +    if(null != m_countMatchPattern)
  +      m_countMatchPattern.fixupVariables(vnames, cstate.getGlobalsSize());
  +    if(null != m_format_avt)
  +      m_format_avt.fixupVariables(vnames, cstate.getGlobalsSize());
  +    if(null != m_fromMatchPattern)
  +      m_fromMatchPattern.fixupVariables(vnames, cstate.getGlobalsSize());
  +    if(null != m_groupingSeparator_avt)
  +      m_groupingSeparator_avt.fixupVariables(vnames, cstate.getGlobalsSize());
  +    if(null != m_groupingSize_avt)
  +      m_groupingSize_avt.fixupVariables(vnames, cstate.getGlobalsSize());
  +    if(null != m_lang_avt)
  +      m_lang_avt.fixupVariables(vnames, cstate.getGlobalsSize());
  +    if(null != m_lettervalue_avt)
  +      m_lettervalue_avt.fixupVariables(vnames, cstate.getGlobalsSize());
  +    if(null != m_valueExpr)
  +      m_valueExpr.fixupVariables(vnames, cstate.getGlobalsSize());
  +  }
  +
   
     /**
      * Get an int constant identifying the type of element.
  
  
  
  1.9.2.3   +16 -0     xml-xalan/java/src/org/apache/xalan/templates/ElemPI.java
  
  Index: ElemPI.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemPI.java,v
  retrieving revision 1.9.2.2
  retrieving revision 1.9.2.3
  diff -u -r1.9.2.2 -r1.9.2.3
  --- ElemPI.java	2001/05/06 02:09:28	1.9.2.2
  +++ ElemPI.java	2001/06/11 20:16:17	1.9.2.3
  @@ -113,6 +113,22 @@
     {
       return m_name_atv;
     }
  +  
  +  /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    super.compose(sroot);
  +    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
  +    if(null != m_name_atv)
  +      m_name_atv.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
  +  }
  +
  +
   
     /**
      * Get an int constant identifying the type of element.
  
  
  
  1.10.2.2  +31 -20    xml-xalan/java/src/org/apache/xalan/templates/ElemParam.java
  
  Index: ElemParam.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemParam.java,v
  retrieving revision 1.10.2.1
  retrieving revision 1.10.2.2
  diff -u -r1.10.2.1 -r1.10.2.2
  --- ElemParam.java	2001/04/10 18:44:49	1.10.2.1
  +++ ElemParam.java	2001/06/11 20:16:18	1.10.2.2
  @@ -61,6 +61,7 @@
   import org.xml.sax.*;
   
   import org.apache.xpath.*;
  +import org.apache.xpath.objects.XObject;
   import org.apache.xalan.trace.*;
   import org.apache.xml.utils.QName;
   import org.apache.xalan.transformer.TransformerImpl;
  @@ -81,6 +82,7 @@
    */
   public class ElemParam extends ElemVariable
   {
  +  int m_qnameID;
   
     /**
      * Constructor ElemParam
  @@ -122,12 +124,22 @@
     }
   
     /**
  -   * Execute a parameter declaration.  There are two elements that can
  -   * be used to bind variables: xsl:variable and xsl:param. The
  -   * difference is that the value specified on the xsl:param variable
  -   * is only a default value for the binding; when the template or
  -   * stylesheet within which the xsl:param element occurs is invoked,
  -   * parameters may be passed that are used in place of the default values.
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    super.compose(sroot);
  +    m_qnameID = sroot.getComposeState().getQNameID(m_qname);
  +    if(m_parentNode.getXSLToken() == Constants.ELEMNAME_TEMPLATE)
  +      ((ElemTemplate)m_parentNode).m_inArgsSize++;
  +  }
  +  
  +  /**
  +   * Execute a variable declaration and push it onto the variable stack.
  +   * @see <a href="http://www.w3.org/TR/xslt#variables">variables in XSLT Specification</a>
      *
      * @param transformer non-null reference to the the current transform-time state.
      * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
  @@ -135,23 +147,22 @@
      *
      * @throws TransformerException
      */
  -  public void execute(
  -          TransformerImpl transformer)
  -            throws TransformerException
  +  public void execute(TransformerImpl transformer) throws TransformerException
     {
  -
  +    if (TransformerImpl.S_DEBUG)
  +      transformer.getTraceManager().fireTraceEvent(this);
  +      
       VariableStack vars = transformer.getXPathContext().getVarStack();
  -    Arg arg = vars.getParamArg(getName());
  -
  -    if (null == arg)
  -    {
  -      super.execute(transformer);
  -    }
  -    else
  +    
  +    if(!vars.isLocalSet(m_index))
       {
  -      arg.setIsVisible(true);
  -      if (TransformerImpl.S_DEBUG)
  -        transformer.getTraceManager().fireTraceEvent(this);
  +
  +      int sourceNode = transformer.getXPathContext().getCurrentNode();
  +      XObject var = getValue(transformer, sourceNode);
  +  
  +      // transformer.getXPathContext().getVarStack().pushVariable(m_qname, var);
  +      transformer.getXPathContext().getVarStack().setLocalVariable(m_index, var);
       }
     }
  +  
   }
  
  
  
  1.6.2.1   +24 -0     xml-xalan/java/src/org/apache/xalan/templates/ElemSort.java
  
  Index: ElemSort.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemSort.java,v
  retrieving revision 1.6
  retrieving revision 1.6.2.1
  diff -u -r1.6 -r1.6.2.1
  --- ElemSort.java	2001/01/02 03:36:46	1.6
  +++ ElemSort.java	2001/06/11 20:16:18	1.6.2.1
  @@ -359,4 +359,28 @@
       //" to " + this.m_elemName);
       return null;
     }
  +  
  +  /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) 
  +    throws javax.xml.transform.TransformerException
  +  {
  +    super.compose(sroot);
  +    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  +    java.util.Vector vnames = cstate.getVariableNames();
  +    if(null != m_caseorder_avt)
  +      m_caseorder_avt.fixupVariables(vnames, cstate.getGlobalsSize());
  +    if(null != m_dataType_avt)
  +      m_dataType_avt.fixupVariables(vnames, cstate.getGlobalsSize());
  +    if(null != m_lang_avt)
  +      m_lang_avt.fixupVariables(vnames, cstate.getGlobalsSize());
  +    if(null != m_order_avt)
  +      m_order_avt.fixupVariables(vnames, cstate.getGlobalsSize());
  +    if(null != m_selectExpression)
  +      m_selectExpression.fixupVariables(vnames, cstate.getGlobalsSize());
  +  }
   }
  
  
  
  1.12.2.2  +50 -0     xml-xalan/java/src/org/apache/xalan/templates/ElemTemplate.java
  
  Index: ElemTemplate.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemTemplate.java,v
  retrieving revision 1.12.2.1
  retrieving revision 1.12.2.2
  diff -u -r1.12.2.1 -r1.12.2.2
  --- ElemTemplate.java	2001/04/10 18:44:49	1.12.2.1
  +++ ElemTemplate.java	2001/06/11 20:16:18	1.12.2.2
  @@ -355,6 +355,56 @@
     {
       return Constants.ELEMNAME_TEMPLATE_STRING;
     }
  +  
  +  /**
  +   * The stack frame size for this template, which is equal to the maximum number 
  +   * of params and variables that can be declared in the template at one time.
  +   */
  +  public int m_frameSize;
  +  
  +  /**
  +   * The size of the portion of the stack frame that can hold parameter 
  +   * arguments.
  +   */
  +  int m_inArgsSize;
  +  
  +  /**
  +   * List of namespace/local-name pairs, DTM style, that are unique 
  +   * qname identifiers for the arguments.  The position of a given qname 
  +   * in the list is the argument ID, and thus the position in the stack
  +   * frame.
  +   */
  +  private int[] m_argsQNameIDs;
  +  
  +  /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    super.compose(sroot);
  +    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  +    java.util.Vector vnames = cstate.getVariableNames();
  +    if(null != m_matchPattern)
  +      m_matchPattern.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
  +      
  +    cstate.resetStackFrameSize();
  +    m_inArgsSize = 0;
  +  }
  +  
  +  /**
  +   * This after the template's children have been composed.
  +   */
  +  public void endCompose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  +    super.endCompose(sroot);
  +    m_frameSize = cstate.getFrameSize();
  +    
  +    cstate.resetStackFrameSize();
  +  }
   
     /**
      * Copy the template contents into the result tree.
  
  
  
  1.38.2.6  +24 -1     xml-xalan/java/src/org/apache/xalan/templates/ElemTemplateElement.java
  
  Index: ElemTemplateElement.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemTemplateElement.java,v
  retrieving revision 1.38.2.5
  retrieving revision 1.38.2.6
  diff -u -r1.38.2.5 -r1.38.2.6
  --- ElemTemplateElement.java	2001/06/04 07:52:50	1.38.2.5
  +++ ElemTemplateElement.java	2001/06/11 20:16:19	1.38.2.6
  @@ -231,14 +231,26 @@
      * values that may be based on some other property that
      * depends on recomposition.
      */
  -  public void compose() throws TransformerException
  +  public void compose(StylesheetRoot sroot) throws TransformerException
     {
       resolvePrefixTables();
       ElemTemplateElement t = getFirstChildElem();
       m_hasTextLitOnly = ((t != null) 
                 && (t.getXSLToken() == Constants.ELEMNAME_TEXTLITERALRESULT) 
                 && (t.getNextSiblingElem() == null));
  +              
  +    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  +    cstate.pushStackMark();
     }
  +  
  +  /**
  +   * This after the template's children have been composed.
  +   */
  +  public void endCompose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  +    cstate.popStackMark();
  +  }
   
     /**
      * Validate that the string is an NCName.
  @@ -707,6 +719,17 @@
      * @serial
      */
     private boolean m_hasTextLitOnly = false;
  +
  +  /**
  +   * Tell if this element only has one text child, for optimization purposes.
  +   * @serial
  +   */
  +  protected boolean m_hasVariableDecl = false;
  +  
  +  public boolean hasVariableDecl()
  +  {
  +    return m_hasVariableDecl;
  +  }
   
     /**
      * Set the "xml:space" attribute.
  
  
  
  1.13.2.8  +33 -10    xml-xalan/java/src/org/apache/xalan/templates/ElemValueOf.java
  
  Index: ElemValueOf.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemValueOf.java,v
  retrieving revision 1.13.2.7
  retrieving revision 1.13.2.8
  diff -u -r1.13.2.7 -r1.13.2.8
  --- ElemValueOf.java	2001/06/08 19:01:59	1.13.2.7
  +++ ElemValueOf.java	2001/06/11 20:16:19	1.13.2.8
  @@ -206,6 +206,28 @@
     }
   
     /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   *
  +   * NEEDSDOC @param sroot
  +   *
  +   * @throws TransformerException
  +   */
  +  public void compose(StylesheetRoot sroot) throws TransformerException
  +  {
  +
  +    super.compose(sroot);
  +
  +    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
  +
  +    if (null != m_selectExpression)
  +      m_selectExpression.fixupVariables(
  +        vnames, sroot.getComposeState().getGlobalsSize());
  +  }
  +
  +  /**
      * Return the node name.
      *
      * @return The node name
  @@ -259,7 +281,7 @@
           {
             dtm.dispatchCharactersEvents(child, rth, false);
   
  -         //if (TransformerImpl.S_DEBUG)
  +          //if (TransformerImpl.S_DEBUG)
             //  transformer.getTraceManager().fireSelectedEvent(child, this,
             //          "select", m_selectExpression, value);
           }
  @@ -286,19 +308,20 @@
   
           try
           {
  -          Expression expr = m_selectExpression.getExpression();          
  +          Expression expr = m_selectExpression.getExpression();
   
             if (TransformerImpl.S_DEBUG)
  -					{
  -						XObject obj = expr.execute(xctxt);
  -						obj.dispatchCharactersEvents(rth);
  +          {
  +            XObject obj = expr.execute(xctxt);
  +
  +            obj.dispatchCharactersEvents(rth);
               transformer.getTraceManager().fireSelectedEvent(current, this,
                       "select", m_selectExpression, obj);
  -					}
  -					else
  -					{
  -						expr.executeCharsToContentHandler(xctxt, rth);
  -					}
  +          }
  +          else
  +          {
  +            expr.executeCharsToContentHandler(xctxt, rth);
  +          }
           }
           finally
           {
  
  
  
  1.10.2.5  +134 -14   xml-xalan/java/src/org/apache/xalan/templates/ElemVariable.java
  
  Index: ElemVariable.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemVariable.java,v
  retrieving revision 1.10.2.4
  retrieving revision 1.10.2.5
  diff -u -r1.10.2.4 -r1.10.2.5
  --- ElemVariable.java	2001/06/04 21:25:49	1.10.2.4
  +++ ElemVariable.java	2001/06/11 20:16:19	1.10.2.5
  @@ -65,6 +65,7 @@
   import org.apache.xpath.objects.XObject;
   import org.apache.xpath.objects.XString;
   import org.apache.xpath.objects.XRTreeFrag;
  +import org.apache.xpath.objects.XRTreeFragSelectWrapper;
   import org.apache.xml.utils.QName;
   import org.apache.xalan.trace.SelectionEvent;
   import org.apache.xalan.res.XSLTErrorResources;
  @@ -86,6 +87,11 @@
    */
   public class ElemVariable extends ElemTemplateElement
   {
  +  /**
  +   * This is the index into the stack frame.  If the index is above the 
  +   * global area, it will have to be offset at execution time.
  +   */
  +  protected int m_index;
   
     /**
      * Constructor ElemVariable
  @@ -133,7 +139,7 @@
      * The value of the "name" attribute.
      * @serial
      */
  -  private QName m_qname;
  +  protected QName m_qname;
   
     /**
      * Set the "name" attribute.
  @@ -175,7 +181,7 @@
      * Set if this is a top-level variable or param, or not.
      * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
      *
  -   * @param v Boolean indicating whether this is a top-level variable 
  +   * @param v Boolean indicating whether this is a top-level variable
      * or param, or not.
      */
     public void setIsTopLevel(boolean v)
  @@ -187,7 +193,7 @@
      * Get if this is a top-level variable or param, or not.
      * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
      *
  -   * @return Boolean indicating whether this is a top-level variable 
  +   * @return Boolean indicating whether this is a top-level variable
      * or param, or not.
      */
     public boolean getIsTopLevel()
  @@ -245,9 +251,7 @@
      *
      * @throws TransformerException
      */
  -  public void execute(
  -          TransformerImpl transformer)
  -            throws TransformerException
  +  public void execute(TransformerImpl transformer) throws TransformerException
     {
   
       if (TransformerImpl.S_DEBUG)
  @@ -256,7 +260,8 @@
       int sourceNode = transformer.getXPathContext().getCurrentNode();
       XObject var = getValue(transformer, sourceNode);
   
  -    transformer.getXPathContext().getVarStack().pushVariable(m_qname, var);
  +    // transformer.getXPathContext().getVarStack().pushVariable(m_qname, var);
  +    transformer.getXPathContext().getVarStack().setLocalVariable(m_index, var);
     }
   
     /**
  @@ -275,18 +280,20 @@
   
       XObject var;
       XPathContext xctxt = transformer.getXPathContext();
  +
       xctxt.pushCurrentNode(sourceNode);
   
       try
       {
         if (null != m_selectPattern)
  -      { 
  +      {
           var = m_selectPattern.execute(xctxt, sourceNode, this);
  -        if(var.getType() == XObject.CLASS_NODESET)
  -          ((org.apache.xpath.objects.XNodeSet)var).allowDetachToRelease(false);
  -        if(TransformerImpl.S_DEBUG)
  -          transformer.getTraceManager().fireSelectedEvent(sourceNode, this, 
  -                                        "select", m_selectPattern, var);
  +
  +        var.allowDetachToRelease(false);
  +
  +        if (TransformerImpl.S_DEBUG)
  +          transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
  +                  "select", m_selectPattern, var);
         }
         else if (null == getFirstChildElem())
         {
  @@ -294,9 +301,10 @@
         }
         else
         {
  -  
  +
           // Use result tree fragment
           int df = transformer.transformToRTF(this);
  +
           var = new XRTreeFrag(df, xctxt);
         }
       }
  @@ -307,8 +315,109 @@
   
       return var;
     }
  +  
  +  
  +  /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    // See if we can reduce an RTF to a select with a string expression.
  +    if(null == m_selectPattern)
  +    {
  +      XPath newSelect = rewriteChildToExpression(this);
  +      if(null != newSelect)
  +        m_selectPattern = newSelect;
  +    }
  +    
  +    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  +    
  +    // This should be done before addVariableName, so we don't have visibility 
  +    // to the variable now being defined.
  +    java.util.Vector vnames = cstate.getVariableNames();
  +    if(null != m_selectPattern)
  +      m_selectPattern.fixupVariables(vnames, cstate.getGlobalsSize());
  +      
  +    // Only add the variable if this is not a global.  If it is a global, 
  +    // it was already added by stylesheet root.
  +    if(!(m_parentNode instanceof Stylesheet))
  +      m_index = cstate.addVariableName(m_qname) - cstate.getGlobalsSize();
  +    
  +    // This has to be done after the addVariableName, so that the variable 
  +    // pushed won't be immediately popped again in endCompose.
  +    super.compose(sroot);
  +  }
  +  
  +  
  +//  /**
  +//   * This after the template's children have been composed.
  +//   */
  +//  public void endCompose() throws TransformerException
  +//  {
  +//    super.endCompose();
  +//  }
  +
   
     /**
  +   * If the children of a variable is a single xsl:value-of or text literal, 
  +   * it is cheaper to evaluate this as an expression, so try and adapt the 
  +   * child an an expression.
  +   *
  +   * @param varElem Should be a ElemParam, ElemVariable, or ElemWithParam.
  +   *
  +   * @return An XPath if rewrite is possible, else null.
  +   *
  +   * @throws TransformerException
  +   */
  +  static XPath rewriteChildToExpression(ElemTemplateElement varElem)
  +          throws TransformerException
  +  {
  +
  +    ElemTemplateElement t = varElem.getFirstChildElem();
  +
  +    // Down the line this can be done with multiple string objects using 
  +    // the concat function.
  +    if (null != t && null == t.getNextSiblingElem())
  +    {
  +      int etype = t.getXSLToken();
  +
  +      if (Constants.ELEMNAME_VALUEOF == etype)
  +      {
  +        ElemValueOf valueof = (ElemValueOf) t;
  +
  +        // %TBD% I'm worried about extended attributes here.
  +        if (valueof.getDisableOutputEscaping() == false
  +                && valueof.getDOMBackPointer() == null)
  +        {
  +          varElem.m_firstChild = null;
  +
  +          return new XPath(new XRTreeFragSelectWrapper(valueof.getSelect().getExpression()));
  +        }
  +      }
  +      else if (Constants.ELEMNAME_TEXTLITERALRESULT == etype)
  +      {
  +        ElemTextLiteral lit = (ElemTextLiteral) t;
  +
  +        if (lit.getDisableOutputEscaping() == false
  +                && lit.getDOMBackPointer() == null)
  +        {
  +          String str = lit.getNodeValue();
  +          XString xstr = new XString(str);
  +
  +          varElem.m_firstChild = null;
  +
  +          return new XPath(new XRTreeFragSelectWrapper(xstr));
  +        }
  +      }
  +    }
  +
  +    return null;
  +  }
  +
  +  /**
      * This function is called during recomposition to
      * control how this element is composed.
      * @param root The root stylesheet for this transformation.
  @@ -316,6 +425,17 @@
     public void recompose(StylesheetRoot root)
     {
       root.recomposeVariables(this);
  +  }
  +  
  +  /**
  +   * Set the parent as an ElemTemplateElement.
  +   *
  +   * @param parent This node's parent as an ElemTemplateElement
  +   */
  +  public void setParentElem(ElemTemplateElement p)
  +  {
  +    super.setParentElem(p);
  +    p.m_hasVariableDecl = true;
     }
   
   }
  
  
  
  1.5.2.1   +15 -0     xml-xalan/java/src/org/apache/xalan/templates/ElemWhen.java
  
  Index: ElemWhen.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemWhen.java,v
  retrieving revision 1.5
  retrieving revision 1.5.2.1
  diff -u -r1.5 -r1.5.2.1
  --- ElemWhen.java	2001/01/02 03:36:47	1.5
  +++ ElemWhen.java	2001/06/11 20:16:20	1.5.2.1
  @@ -121,6 +121,21 @@
     {
       return Constants.ELEMNAME_WHEN;
     }
  +  
  +  /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) 
  +    throws javax.xml.transform.TransformerException
  +  {
  +    super.compose(sroot);
  +    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
  +    if(null != m_test)
  +      m_test.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
  +  }
   
     /**
      * Return the node name.
  
  
  
  1.6.2.1   +102 -0    xml-xalan/java/src/org/apache/xalan/templates/ElemWithParam.java
  
  Index: ElemWithParam.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemWithParam.java,v
  retrieving revision 1.6
  retrieving revision 1.6.2.1
  diff -u -r1.6 -r1.6.2.1
  --- ElemWithParam.java	2001/01/02 03:36:47	1.6
  +++ ElemWithParam.java	2001/06/11 20:16:20	1.6.2.1
  @@ -61,9 +61,13 @@
   import org.xml.sax.*;
   
   import org.apache.xpath.*;
  +import org.apache.xpath.objects.XString;
  +import org.apache.xpath.objects.XObject;
  +import org.apache.xpath.objects.XRTreeFrag;
   import org.apache.xml.utils.QName;
   import org.apache.xalan.res.XSLTErrorResources;
   import org.apache.xalan.transformer.TransformerImpl;
  +import javax.xml.transform.TransformerException;
   
   /**
    * <meta name="usage" content="advanced"/>
  @@ -80,6 +84,11 @@
    */
   public class ElemWithParam extends ElemTemplateElement
   {
  +  /**
  +   * This is the index to the stack frame being called, <emph>not</emph> the 
  +   * stack frame that contains this element.
  +   */
  +  int m_index;
   
     /**
      * The "select" attribute, which specifies the value of the
  @@ -120,6 +129,8 @@
      * @serial
      */
     private QName m_qname = null;
  +  
  +  int m_qnameID;
   
     /**
      * Set the "name" attribute.
  @@ -155,6 +166,7 @@
       return Constants.ELEMNAME_WITHPARAM;
     }
   
  +
     /**
      * Return the node name.
      *
  @@ -164,4 +176,94 @@
     {
       return Constants.ELEMNAME_WITHPARAM_STRING;
     }
  +  
  +  /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) throws TransformerException
  +  {
  +    // See if we can reduce an RTF to a select with a string expression.
  +    if(null == m_selectPattern)
  +    {
  +      XPath newSelect = ElemVariable.rewriteChildToExpression(this);
  +      if(null != newSelect)
  +        m_selectPattern = newSelect;
  +    }
  +    m_qnameID = sroot.getComposeState().getQNameID(m_qname);
  +    super.compose(sroot);
  +    
  +    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
  +    if(null != m_selectPattern)
  +      m_selectPattern.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
  +      
  +    // m_index must be resolved by ElemApplyTemplates and ElemCallTemplate!
  +  }
  +  
  +  /**
  +   * Set the parent as an ElemTemplateElement.
  +   *
  +   * @param parent This node's parent as an ElemTemplateElement
  +   */
  +  public void setParentElem(ElemTemplateElement p)
  +  {
  +    super.setParentElem(p);
  +    p.m_hasVariableDecl = true;
  +  }
  +  
  +  /**
  +   * Get the XObject representation of the variable.
  +   *
  +   * @param transformer non-null reference to the the current transform-time state.
  +   * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
  +   *
  +   * @return the XObject representation of the variable.
  +   *
  +   * @throws TransformerException
  +   */
  +  public XObject getValue(TransformerImpl transformer, int sourceNode)
  +          throws TransformerException
  +  {
  +
  +    XObject var;
  +    XPathContext xctxt = transformer.getXPathContext();
  +
  +    xctxt.pushCurrentNode(sourceNode);
  +
  +    try
  +    {
  +      if (null != m_selectPattern)
  +      {
  +        var = m_selectPattern.execute(xctxt, sourceNode, this);
  +
  +        var.allowDetachToRelease(false);
  +
  +        if (TransformerImpl.S_DEBUG)
  +          transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
  +                  "select", m_selectPattern, var);
  +      }
  +      else if (null == getFirstChildElem())
  +      {
  +        var = XString.EMPTYSTRING;
  +      }
  +      else
  +      {
  +
  +        // Use result tree fragment
  +        int df = transformer.transformToRTF(this);
  +
  +        var = new XRTreeFrag(df, xctxt);
  +      }
  +    }
  +    finally
  +    {
  +      xctxt.popCurrentNode();
  +    }
  +
  +    return var;
  +  }
  +
  +
   }
  
  
  
  1.7.2.1   +17 -0     xml-xalan/java/src/org/apache/xalan/templates/KeyDeclaration.java
  
  Index: KeyDeclaration.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/KeyDeclaration.java,v
  retrieving revision 1.7
  retrieving revision 1.7.2.1
  diff -u -r1.7 -r1.7.2.1
  --- KeyDeclaration.java	2001/01/02 03:36:47	1.7
  +++ KeyDeclaration.java	2001/06/11 20:16:20	1.7.2.1
  @@ -180,6 +180,23 @@
     {
       return m_use;
     }
  +  
  +  /**
  +   * This function is called after everything else has been
  +   * recomposed, and allows the template to set remaining
  +   * values that may be based on some other property that
  +   * depends on recomposition.
  +   */
  +  public void compose(StylesheetRoot sroot) 
  +    throws javax.xml.transform.TransformerException
  +  {
  +    super.compose(sroot);
  +    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
  +    if(null != m_matchPattern)
  +      m_matchPattern.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
  +    if(null != m_use)
  +      m_use.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
  +  }
   
     /**
      * This function is called during recomposition to
  
  
  
  1.13.2.2  +2 -2      xml-xalan/java/src/org/apache/xalan/templates/OutputProperties.java
  
  Index: OutputProperties.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/OutputProperties.java,v
  retrieving revision 1.13.2.1
  retrieving revision 1.13.2.2
  diff -u -r1.13.2.1 -r1.13.2.2
  --- OutputProperties.java	2001/05/27 03:05:14	1.13.2.1
  +++ OutputProperties.java	2001/06/11 20:16:21	1.13.2.2
  @@ -846,10 +846,10 @@
      * values that may be based on some other property that
      * depends on recomposition.
      */
  -  public void compose() throws TransformerException
  +  public void compose(StylesheetRoot sroot) throws TransformerException
     {
   
  -    super.compose();
  +    super.compose(sroot);
   
       m_propertiesLevels = null;
     }
  
  
  
  1.40.2.4  +182 -6    xml-xalan/java/src/org/apache/xalan/templates/StylesheetRoot.java
  
  Index: StylesheetRoot.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/StylesheetRoot.java,v
  retrieving revision 1.40.2.3
  retrieving revision 1.40.2.4
  diff -u -r1.40.2.3 -r1.40.2.4
  --- StylesheetRoot.java	2001/06/03 03:24:21	1.40.2.3
  +++ StylesheetRoot.java	2001/06/11 20:16:21	1.40.2.4
  @@ -88,6 +88,8 @@
   import javax.xml.transform.OutputKeys;
   import javax.xml.transform.ErrorListener;
   
  +import org.apache.xml.dtm.ref.ExpandedNameTable;
  +
   /**
    * <meta name="usage" content="general"/>
    * This class represents the root object of the stylesheet tree.
  @@ -268,15 +270,17 @@
       for (int i = recomposableElements.size() - 1; i >= 0; i--)
         ((ElemTemplateElement) recomposableElements.elementAt(i)).recompose(this);
       
  +    initComposeState();
  +
       // Need final composition of TemplateList.  This adds the wild cards onto the chains.
  -    m_templateList.compose();
  +    m_templateList.compose(this);
       
       // Need to clear check for properties at the same import level.
  -    m_outputProperties.compose();
  -
  +    m_outputProperties.compose(this);
  +    
       // Now call the compose() method on every element to give it a chance to adjust
       // based on composed values.
  -
  +    
       n = getGlobalImportCount();
   
       for (int i = 0; i < n; i++)
  @@ -289,6 +293,8 @@
           composeTemplates(included);
         }
       }
  +    
  +    clearComposeState();
     }
   
     /**
  @@ -298,16 +304,18 @@
      * the composed method called on it, and will have it's children's composed 
      * methods called.
      */
  -  static void composeTemplates(ElemTemplateElement templ) throws TransformerException
  +  void composeTemplates(ElemTemplateElement templ) throws TransformerException
     {
   
  -    templ.compose();
  +    templ.compose(this);
   
       for (ElemTemplateElement child = templ.getFirstChildElem();
               child != null; child = child.getNextSiblingElem())
       {
         composeTemplates(child);
       }
  +    
  +    templ.endCompose(this);
     }
   
     /**
  @@ -942,7 +950,26 @@
     {
       return m_defaultRootRule;
     }
  +  
  +  /**
  +   * <meta name="usage" content="advanced"/>
  +   * The start rule to kick off the transformation.
  +   * @serial
  +   */
  +  private ElemTemplate m_startRule;
  +
  +  /**
  +   * <meta name="usage" content="advanced"/>
  +   * Get the default template for a root node.
  +   *
  +   * @return The default template for a root node.
  +   */
  +  public final ElemTemplate getStartRule()
  +  {
  +    return m_startRule;
  +  }
   
  +
     /**
      * Used for default selection.
      * @serial
  @@ -971,6 +998,8 @@
       childrenElement.setIsDefaultTemplate(true);
       childrenElement.setSelect(m_selectDefault);
       m_defaultRule.appendChild(childrenElement);
  +    
  +    m_startRule = m_defaultRule;
   
       // -----------------------------
       m_defaultTextRule = new ElemTemplate();
  @@ -1078,4 +1107,151 @@
           }
         }
       } // end QuickSort2  */
  +    
  +    private ComposeState m_composeState;
  +    
  +    /**
  +     * Initialize a new ComposeState.
  +     */
  +    void initComposeState()
  +    {
  +      m_composeState = new ComposeState();
  +    }
  +
  +    /**
  +     * Return class to track state global state during the compose() operation.
  +     * @return ComposeState reference, or null if endCompose has been called.
  +     */
  +    ComposeState getComposeState()
  +    {
  +      return m_composeState;
  +    }
  +    
  +    /**
  +     * Clear the compose state.
  +     */
  +    private void clearComposeState()
  +    {
  +      m_composeState = null;
  +    }
  +    
  +    /**
  +     * Class to track state global state during the compose() operation.
  +     */
  +    class ComposeState
  +    {
  +      ComposeState()
  +      {
  +        int size = m_variables.size();
  +        for (int i = 0; i < size; i++) 
  +        {
  +          ElemVariable ev = (ElemVariable)m_variables.elementAt(i);
  +          m_variableNames.addElement(ev.getName());
  +        }
  +        
  +      }
  +      
  +      private ExpandedNameTable m_ent = new ExpandedNameTable();
  +      
  +      /**
  +       * Given a qualified name, return an integer ID that can be 
  +       * quickly compared.
  +       *
  +       * @param qname a qualified name object, must not be null.
  +       *
  +       * @return the expanded-name id of the qualified name.
  +       */
  +      public int getQNameID(QName qname)
  +      {
  +        
  +        return m_ent.getExpandedTypeID(qname.getNamespace(), 
  +                                       qname.getLocalName(),
  +                                       // The type doesn't matter for our 
  +                                       // purposes. 
  +                                       org.apache.xml.dtm.DTM.ELEMENT_NODE);
  +      }
  +      
  +      /**
  +       * A Vector of the current params and QNames within the current template.
  +       * Set by ElemTemplate and used by ProcessorVariable.
  +       */
  +      private java.util.Vector m_variableNames = new java.util.Vector();
  +            
  +      /**
  +       * Add the name of a qualified name within the template.  The position in 
  +       * the vector is its ID.
  +       * @param qname A qualified name of a param or variable, should be non-null.
  +       * @return the index where the variable was added.
  +       */
  +      int addVariableName(final org.apache.xml.utils.QName qname)
  +      {
  +        int pos = m_variableNames.size();
  +        m_variableNames.addElement(qname);
  +        int frameSize = m_variableNames.size() - getGlobalsSize();
  +        if(frameSize > m_maxStackFrameSize)
  +          m_maxStackFrameSize++;
  +        return pos;
  +      }
  +      
  +      void resetStackFrameSize()
  +      {
  +        m_maxStackFrameSize = 0;
  +      }
  +      
  +      int getFrameSize()
  +      {
  +        return m_maxStackFrameSize;
  +      }
  +      
  +      /**
  +       * Get the current size of the stack frame.  Use this to record the position 
  +       * in a template element at startElement, so that it can be popped 
  +       * at endElement.
  +       */
  +      int getCurrentStackFrameSize()
  +      {
  +        return m_variableNames.size();
  +      }
  +      
  +      /**
  +       * Set the current size of the stack frame.
  +       */
  +      void setCurrentStackFrameSize(int sz)
  +      {
  +        m_variableNames.setSize(sz);
  +      }
  +      
  +      int getGlobalsSize()
  +      {
  +        return m_variables.size();
  +      }
  +      
  +      IntStack m_marks = new IntStack();
  +      
  +      void pushStackMark()
  +      {
  +        m_marks.push(getCurrentStackFrameSize());
  +      }
  +      
  +      void popStackMark()
  +      {
  +        int mark = m_marks.pop();
  +        setCurrentStackFrameSize(mark);
  +      }
  +      
  +      /**
  +       * Get the Vector of the current params and QNames to be collected 
  +       * within the current template.
  +       * @return A reference to the vector of variable names.  The reference 
  +       * returned is owned by this class, and so should not really be mutated, or 
  +       * stored anywhere.
  +       */
  +      java.util.Vector getVariableNames()
  +      {
  +        return m_variableNames;
  +      }
  +      
  +      private int m_maxStackFrameSize;
  +
  +    }
   }
  
  
  
  1.30.2.5  +1 -1      xml-xalan/java/src/org/apache/xalan/templates/TemplateList.java
  
  Index: TemplateList.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/TemplateList.java,v
  retrieving revision 1.30.2.4
  retrieving revision 1.30.2.5
  diff -u -r1.30.2.4 -r1.30.2.5
  --- TemplateList.java	2001/06/04 07:52:52	1.30.2.4
  +++ TemplateList.java	2001/06/11 20:16:21	1.30.2.5
  @@ -204,7 +204,7 @@
      * After all templates have been added, this function
      * should be called.
      */
  -  public void compose()
  +  public void compose(StylesheetRoot sroot)
     {
   
       if (DEBUG)
  
  
  
  1.5.2.2   +15 -13    xml-xalan/java/src/org/apache/xalan/templates/XUnresolvedVariable.java
  
  Index: XUnresolvedVariable.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/XUnresolvedVariable.java,v
  retrieving revision 1.5.2.1
  retrieving revision 1.5.2.2
  diff -u -r1.5.2.1 -r1.5.2.2
  --- XUnresolvedVariable.java	2001/04/10 18:44:53	1.5.2.1
  +++ XUnresolvedVariable.java	2001/06/11 20:16:22	1.5.2.2
  @@ -156,20 +156,22 @@
       VariableStack vars = xctxt.getVarStack();
       
       // These three statements need to be combined into one operation.
  -    int savedStart = vars.getSearchStart();
  -    vars.setSearchStart(m_varStackPos);
  -    vars.pushContextPosition(m_varStackContext);
  +    int currentFrame = vars.getStackFrame();
  +    vars.setStackFrame(m_varStackPos);
   
  -    m_doneEval = false;
  -    ElemVariable velem = (ElemVariable)m_obj;
  -    XObject var = velem.getValue(m_transformer, m_context);
  -    
  -    // These two statements need to be combined into one operation.
  -    vars.setSearchStart(savedStart);
  -    vars.popContextPosition();
  -    m_doneEval = true;
  -
  -    return var;
  +    try
  +    {
  +      m_doneEval = false;
  +      ElemVariable velem = (ElemVariable)m_obj;
  +      XObject var = velem.getValue(m_transformer, m_context);
  +      m_doneEval = true;
  +      return var;
  +    }
  +    finally
  +    {
  +      // These two statements need to be combined into one operation.
  +      vars.setStackFrame(currentFrame);
  +    }
     }
     
     /**
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.6.2.4   +21 -5     xml-xalan/java/src/org/apache/xalan/transformer/KeyRefIterator.java
  
  Index: KeyRefIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/KeyRefIterator.java,v
  retrieving revision 1.6.2.3
  retrieving revision 1.6.2.4
  diff -u -r1.6.2.3 -r1.6.2.4
  --- KeyRefIterator.java	2001/05/22 05:48:44	1.6.2.3
  +++ KeyRefIterator.java	2001/06/11 20:16:32	1.6.2.4
  @@ -82,15 +82,15 @@
   
     /** Key name.
      *  @serial         */
  -  private QName m_name;    
  +  private final QName m_name;    
     
     /** Use field of key function.
      *  @serial         */
  -  private XMLString m_lookupKey;  
  +  private final XMLString m_lookupKey;  
     
     /** Main Key iterator for this iterator.
      *  @serial    */
  -  private KeyIterator m_ki;    
  +  private final KeyIterator m_ki;    
     
     /**
      * Get key name
  @@ -185,6 +185,7 @@
      */
     public Object clone() throws CloneNotSupportedException
     {
  +    // I wonder if we really want to clone the second time.  Myriam review.
       KeyRefIterator clone = (KeyRefIterator)super.clone();
       // clone.m_ki = (KeyIterator)m_ki.clone();
   
  @@ -211,9 +212,24 @@
      */
     public void reset()
     {
  -    super.reset();
  -    
  +    // I don't think we want to reset anything but the current position 
  +    // for this specialized iterator.
  +    // super.reset();
  +    // setShouldCacheNodes(true);
       setCurrentPos(0);
  +  }
  +  
  +  /**
  +   *  Detaches the iterator from the set which it iterated over, releasing
  +   * any computational resources and placing the iterator in the INVALID
  +   * state. After<code>detach</code> has been invoked, calls to
  +   * <code>nextNode</code> or<code>previousNode</code> will raise the
  +   * exception INVALID_STATE_ERR.
  +   */
  +  public void detach()
  +  {    
  +    // I don't think we want to detach at all for this iterator.
  +    // Myriam needs to review.  -sb.
     }
   
     
  
  
  
  1.90.2.20 +36 -146   xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java
  
  Index: TransformerImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java,v
  retrieving revision 1.90.2.19
  retrieving revision 1.90.2.20
  diff -u -r1.90.2.19 -r1.90.2.20
  --- TransformerImpl.java	2001/06/08 19:02:07	1.90.2.19
  +++ TransformerImpl.java	2001/06/11 20:16:32	1.90.2.20
  @@ -460,7 +460,7 @@
         m_stackGuard = new StackGuard();
   
         m_xcontext.reset();
  -      m_xcontext.getVarStack().setSize(1);
  +      m_xcontext.getVarStack().reset();
   
         int n = m_currentTemplateElements.length;
         for (int i = 0; i < n; i++) 
  @@ -1237,6 +1237,7 @@
           // ===========
           // System.out.println("Calling applyTemplateToNode - "+Thread.currentThread().getName());
           this.applyTemplateToNode(null, null, node);
  +        // m_stylesheetRoot.getStartRule().execute(this);
   
           // System.out.println("Done with applyTemplateToNode - "+Thread.currentThread().getName());
           if (null != m_resultTreeHandler)
  @@ -1391,10 +1392,10 @@
     {
       m_serializer = s;
     }
  -
  +  
     /**
      * Set a parameter for the templates.
  -   *
  +   * 
      * @param name The name of the parameter.
      * @param namespace The namespace of the parameter.
      * @param value The value object.  This can be any valid Java object
  @@ -1405,11 +1406,22 @@
     public void setParameter(String name, String namespace, Object value)
     {
   
  -    VariableStack varstack = m_xcontext.getVarStack();
  +    VariableStack varstack = getXPathContext().getVarStack();
       QName qname = new QName(namespace, name);
       XObject xobject = XObject.create(value);
  -
  -    varstack.pushOrReplaceParameter(qname, xobject);
  +    
  +    StylesheetRoot sroot = m_stylesheetRoot;
  +    Vector vars = sroot.getVariablesAndParamsComposed();
  +    int i = vars.size();
  +    while (--i >= 0)
  +    {
  +      ElemVariable variable = (ElemVariable)vars.elementAt(i);
  +      if(variable.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE && 
  +         variable.getName().equals(qname))
  +      {
  +          varstack.setGlobalVariable(i, xobject);
  +      }
  +    }
     }
   
     /** NEEDSDOC Field m_userParams          */
  @@ -1596,86 +1608,6 @@
       }
     }
   
  -  /**
  -   * Given a template, search for
  -   * the arguments and push them on the stack.  Also,
  -   * push default arguments on the stack.
  -   * You <em>must</em> call popContext() when you are
  -   * done with the arguments.
  -   *
  -   * @param xctxt The XPath runtime state for this transformation.
  -   * @param xslCallTemplateElement The xsl:call-template element.
  -   * @param sourceNode The Current source tree node.
  -   * @param mode The current xslt mode.
  -   *
  -   * @throws TransformerException
  -   */
  -  public void pushParams(
  -          XPathContext xctxt, ElemCallTemplate xslCallTemplateElement)
  -            throws TransformerException
  -  {
  -
  -    // The trick here is, variables need to be executed outside the context 
  -    // of the current stack frame.
  -    VariableStack vars = xctxt.getVarStack();
  -    int n = xslCallTemplateElement.getParamElemCount();
  -    int paramDeclareContext = vars.getSearchStartOrTop();
  -
  -    vars.pushContextMarker();
  -
  -    int paramReferenceContext = -1;
  -
  -    for (int i = 0; i < n; i++)
  -    {
  -      vars.setSearchStart(paramDeclareContext);
  -
  -      ElemWithParam xslParamElement = xslCallTemplateElement.getParamElem(i);
  -
  -      // Get the argument value as either an expression or 
  -      // a result tree fragment.
  -      XObject var;
  -      XPath param = xslParamElement.getSelect();
  -
  -      if (null != param)
  -      {
  -        int sourceNode = xctxt.getCurrentNode();
  -
  -        var = param.execute(m_xcontext, sourceNode, xslParamElement);
  -      }
  -      else if (null == xslParamElement.getFirstChildElem())
  -      {
  -        var = XString.EMPTYSTRING;
  -      }
  -      else
  -      {
  -        int sourceNode = xctxt.getCurrentNode();
  -
  -        // Use result tree fragment
  -        // %REVIEW% Make sure current node is pushed.
  -        int df = transformToRTF(xslParamElement);
  -
  -        var = new XRTreeFrag(df, xctxt);
  -      }
  -
  -      vars.setSearchStart(paramReferenceContext);
  -      vars.pushVariableArg(new Arg(xslParamElement.getName(), var, true));
  -
  -      //      m_newVars.addElement(new Arg(xslParamElement.getName(), var, true));
  -    }
  -
  -    //    int nNew = m_newVars.size();
  -    //
  -    //    if (nNew > 0)
  -    //    {
  -    //      for (int i = 0; i < nNew; i++)
  -    //      {
  -    //        vars.pushVariableArg((Arg) m_newVars.elementAt(i));
  -    //      }
  -    //
  -    //      // Dragons check: make sure this is nulling the refs.
  -    //      m_newVars.removeAllElements();
  -    //    }
  -  }  // end pushParams method
   
     /**
      * Internal -- push the global variables from the Stylesheet onto
  @@ -1699,62 +1631,26 @@
     protected void pushGlobalVars(int contextNode) throws TransformerException
     {
   
  -    // I'm a little unhappy with this, as it seems like 
  -    // this will make all the variables for all stylesheets 
  -    // in scope, when really only the current stylesheet's 
  -    // global variables should be in scope.  Have to think on 
  -    // this more...
  -    XObject xobj;
       XPathContext xctxt = m_xcontext;
       VariableStack vs = xctxt.getVarStack();
       StylesheetRoot sr = getStylesheet();
       Vector vars = sr.getVariablesAndParamsComposed();
  -    int startGlobals = vs.size();
  +    
       int i = vars.size();
  +    vs.link(i);
   
       while (--i >= 0)
       {
         ElemVariable v = (ElemVariable) vars.elementAt(i);
  -      Arg previouslyDeclared = vs.getDeclaredVariable(v.getName());
  -
  -      if (null != previouslyDeclared)
  -      {
  -        if ((v instanceof ElemParam) && previouslyDeclared.isFromWithParam())
  -        {
  -          previouslyDeclared.setIsVisible(true);
  -        }
  -        else
  -        {
  -          xobj = new XUnresolvedVariable(v, contextNode, this,
  -                                         vs.getSearchStartOrTop(), 0, true);
  -
  -          previouslyDeclared.setVal(xobj);
  -        }
  -
  -        continue;
  -      }
   
         // XObject xobj = v.getValue(this, contextNode);
  -      xobj = new XUnresolvedVariable(v, contextNode, this,
  -                                     vs.getSearchStartOrTop(), 0, true);
  -
  -      vs.pushVariable(v.getName(), xobj);
  -      vs.markGlobalStackFrame();
  -    }
  -
  -    vs.markGlobalStackFrame();
  -
  -    int endGlobals = vs.size();
  -
  -    for (i = startGlobals; i < endGlobals; i++)
  -    {
  -      Arg arg = (Arg) vs.elementAt(i);
  -      XUnresolvedVariable uv = (XUnresolvedVariable) arg.getVal();
  -
  -      uv.setVarStackPos(endGlobals);
  +      XObject xobj = new XUnresolvedVariable(v, contextNode, this,
  +                                     vs.getStackFrame(), 0, true);
  +      
  +      if(null == vs.elementAt(i))                               
  +        vs.setGlobalVariable(i, xobj);
       }
   
  -    vs.pushContextMarker();
     }
   
     /**
  @@ -2016,7 +1912,7 @@
      * @return true if applied a template, false if not.
      */
     public boolean applyTemplateToNode(ElemTemplateElement xslInstruction,  // xsl:apply-templates or xsl:for-each
  -                                     ElemTemplateElement template, int child)
  +                                     ElemTemplate template, int child)
                                                throws TransformerException
     {
   
  @@ -2140,6 +2036,8 @@
           // also unclear that "execute" is really the right name for
           // that entry point.)
           m_xcontext.setSAXLocator(template);
  +        // m_xcontext.getVarStack().link();
  +        m_xcontext.getVarStack().link(template.m_frameSize);
           executeChildTemplates(template, true);
         }
       }
  @@ -2149,6 +2047,7 @@
       }
       finally
       {
  +      m_xcontext.getVarStack().unlink();
         m_xcontext.popCurrentNode();
         popCurrentMatched();
         popElemTemplateElement();
  @@ -2513,18 +2412,12 @@
       }
   
       XPathContext xctxt = m_xcontext;
  -
  -    // Check for infinite loops if we have to.
  -    boolean check = (m_stackGuard.m_recursionLimit > -1);
  -
  -    if (check)
  -      getStackGuard().push(elem, xctxt.getCurrentNode());
   
  -    // We need to push an element frame in the variables stack, 
  -    // so all the variables can be popped at once when we're done.
  -    VariableStack varstack = xctxt.getVarStack();
  -
  -    varstack.pushElemFrame();
  +//    // Check for infinite loops if we have to.
  +//    boolean check = (m_stackGuard.m_recursionLimit > -1);
  +//
  +//    if (check)
  +//      getStackGuard().push(elem, xctxt.getCurrentNode());
   
       xctxt.pushSAXLocatorNull();
       int currentTemplateElementsTop = m_currentTemplateElementsTop;
  @@ -2549,14 +2442,11 @@
       {
         m_currentTemplateElementsTop--;
         xctxt.popSAXLocator();
  -
  -      // Pop all the variables in this element frame.
  -      varstack.popElemFrame();
       }
   
       // Check for infinite loops if we have to
  -    if (check)
  -      getStackGuard().pop();
  +//    if (check)
  +//      getStackGuard().pop();
     }
   
     /**
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.5   +11 -4     xml-xalan/java/src/org/apache/xml/dtm/Attic/Axis.java
  
  Index: Axis.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/Axis.java,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- Axis.java	2001/05/25 17:36:24	1.1.2.4
  +++ Axis.java	2001/06/11 20:16:35	1.1.2.5
  @@ -179,14 +179,20 @@
     public static final int DESCENDANTSFROMROOT = 17;
   
     /**
  +   * A non-xpath axis, returns all nodes that aren't namespaces or attributes, 
  +   * from and including the root.
  +   */
  +  public static final int DESCENDANTSORSELFFROMROOT = 18;
  +
  +  /**
      * A non-xpath axis, returns root only.
      */
  -  public static final int ROOT = 18;
  +  public static final int ROOT = 19;
   
     /**
      * A non-xpath axis, for functions.
      */
  -  public static final int FILTEREDLIST = 19;
  +  public static final int FILTEREDLIST = 20;
   
   
     /** The names of the axes for diagnostic purposes. */
  @@ -210,7 +216,8 @@
       "preceding-and-ancestor",  // 15
       "all",  // 16
       "descendants-from-root",  // 17
  -    "root",  // 18
  -    "filtered-list"  // 19
  +    "descendants-or-self-from-root",  // 18
  +    "root",  // 19
  +    "filtered-list"  // 20
     };
   }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.8   +70 -61    xml-xalan/java/src/org/apache/xml/dtm/ref/Attic/DTMDefaultBase.java
  
  Index: DTMDefaultBase.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/Attic/DTMDefaultBase.java,v
  retrieving revision 1.1.2.7
  retrieving revision 1.1.2.8
  diff -u -r1.1.2.7 -r1.1.2.8
  --- DTMDefaultBase.java	2001/06/11 19:05:05	1.1.2.7
  +++ DTMDefaultBase.java	2001/06/11 20:16:36	1.1.2.8
  @@ -197,6 +197,11 @@
                           DTMWSFilter whiteSpaceFilter,
                           XMLStringFactory xstringfactory, boolean doIndexing)
     {
  +    if(false == doIndexing)
  +    {
  +      m_initialblocksize = 8;
  +      m_blocksize = 16;
  +    }
   
       m_exptype = new int[m_initialblocksize];
       m_level = new byte[m_initialblocksize];
  @@ -973,6 +978,10 @@
       return DTM.NULL;
     }
   
  +  /** Lazily created namespace lists. */
  +  private Vector m_namespaceLists = null;  // on demand
  +
  +
     /** Build table of namespace declaration
      * locations during DTM construction. Table is a Vector of
      * IntVectors containing the namespace node HANDLES declared at
  @@ -1154,33 +1163,33 @@
      */
     public int getFirstNamespaceNode(int nodeHandle, boolean inScope)
     {
  -	if(inScope)
  -	  {	    
  -	    IntVector nsContext=findNamespaceContext(nodeHandle & m_mask);
  -	    if(nsContext==null || nsContext.size()<1)
  -	      return NULL;
  -
  -	    return nsContext.elementAt(0);
  -	  }
  -	else
  -	  {
  -	    // Assume that attributes and namespaces immediately
  -	    // follow the element.
  -	    //
  -	    // %OPT% Would things be faster if all NS nodes were built
  -	    // before all Attr nodes? Some costs at build time for 2nd
  -	    // pass...
  -	    int identity = nodeHandle & m_mask;
  -	    while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
  -	      {
  -		int type = getNodeType(identity);
  -		if (type == DTM.NAMESPACE_NODE)
  -		    return identity | m_dtmIdent;
  -		else if (DTM.ATTRIBUTE_NODE != type)
  -		    break;
  -	      }
  -	    return NULL;
  -	  }
  +        if(inScope)
  +        {      
  +            IntVector nsContext=findNamespaceContext(nodeHandle & m_mask);
  +            if(nsContext==null || nsContext.size()<1)
  +              return NULL;
  +
  +            return nsContext.elementAt(0);
  +          }
  +        else
  +          {
  +            // Assume that attributes and namespaces immediately
  +            // follow the element.
  +            //
  +            // %OPT% Would things be faster if all NS nodes were built
  +            // before all Attr nodes? Some costs at build time for 2nd
  +            // pass...
  +            int identity = nodeHandle & m_mask;
  +            while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
  +              {
  +                int type = getNodeType(identity);
  +                if (type == DTM.NAMESPACE_NODE)
  +                    return identity | m_dtmIdent;
  +                else if (DTM.ATTRIBUTE_NODE != type)
  +                    break;
  +              }
  +            return NULL;
  +          }
     }
   
     /**
  @@ -1198,40 +1207,40 @@
     public int getNextNamespaceNode(int baseHandle, int nodeHandle,
                                     boolean inScope)
     {
  -	if(inScope)
  -	  {
  -	    //Since we've been given the base, try direct lookup
  -	    //(could look from nodeHandle but this is at least one
  -	    //comparison/get-parent faster)
  -	    //IntVector nsContext=findNamespaceContext(nodeHandle & m_mask);
  -
  -		IntVector nsContext=findNamespaceContext(baseHandle & m_mask);
  -
  -	    if(nsContext==null)
  -	      return NULL;
  -	    int i=1 + nsContext.indexOf(nodeHandle);
  -	    if(i<=0 || i==nsContext.size())
  -	      return NULL;
  -
  -	    return nsContext.elementAt(i);
  -	  }
  -	else
  -	  {
  -	    // Assume that attributes and namespace nodes immediately follow the element.
  -	    int identity = nodeHandle & m_mask;
  -	    while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
  -	      {
  -		int type = getNodeType(identity);
  -		if (type == DTM.NAMESPACE_NODE)
  -		  {
  -		    return identity | m_dtmIdent;
  -		  }
  -		else if (type != DTM.ATTRIBUTE_NODE)
  -		  {
  -		    break;
  -		  }
  -	      }
  -	  }
  +        if(inScope)
  +          {
  +            //Since we've been given the base, try direct lookup
  +            //(could look from nodeHandle but this is at least one
  +            //comparison/get-parent faster)
  +            //IntVector nsContext=findNamespaceContext(nodeHandle & m_mask);
  +
  +                IntVector nsContext=findNamespaceContext(baseHandle & m_mask);
  +
  +            if(nsContext==null)
  +              return NULL;
  +            int i=1 + nsContext.indexOf(nodeHandle);
  +            if(i<=0 || i==nsContext.size())
  +              return NULL;
  +
  +            return nsContext.elementAt(i);
  +          }
  +        else
  +          {
  +            // Assume that attributes and namespace nodes immediately follow the element.
  +            int identity = nodeHandle & m_mask;
  +            while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
  +              {
  +                int type = getNodeType(identity);
  +                if (type == DTM.NAMESPACE_NODE)
  +                  {
  +                    return identity | m_dtmIdent;
  +                  }
  +                else if (type != DTM.ATTRIBUTE_NODE)
  +                  {
  +                    break;
  +                  }
  +              }
  +          }
        return DTM.NULL;
     }
   
  
  
  
  1.1.2.9   +221 -28   xml-xalan/java/src/org/apache/xml/dtm/ref/Attic/DTMDefaultBaseTraversers.java
  
  Index: DTMDefaultBaseTraversers.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/Attic/DTMDefaultBaseTraversers.java,v
  retrieving revision 1.1.2.8
  retrieving revision 1.1.2.9
  diff -u -r1.1.2.8 -r1.1.2.9
  --- DTMDefaultBaseTraversers.java	2001/05/30 20:31:00	1.1.2.8
  +++ DTMDefaultBaseTraversers.java	2001/06/11 20:16:37	1.1.2.9
  @@ -173,6 +173,9 @@
       case Axis.DESCENDANTSFROMROOT :
         traverser = new DescendantFromRootTraverser();
         break;
  +    case Axis.DESCENDANTSORSELFFROMROOT :
  +      traverser = new DescendantOrSelfFromRootTraverser();
  +      break;
       case Axis.ROOT :
         traverser = new RootTraverser();
         break;
  @@ -326,6 +329,124 @@
      */
     private class ChildTraverser extends DTMAxisTraverser
     {
  +    
  +    /**
  +     * Get the next indexed node that matches the extended type ID.  Before 
  +     * calling this function, one should first call 
  +     * {@link #isIndexed(int) isIndexed} to make sure that the index can 
  +     * contain nodes that match the given extended type ID.
  +     *
  +     * @param axisRoot The root identity of the axis.
  +     * @param nextPotential The node found must match or occur after this node.
  +     * @param extendedTypeID The extended type ID for the request.
  +     *
  +     * @return The node or NULL if not found.
  +     */
  +    protected int getNextIndexed(int axisRoot, int nextPotential,
  +                                 int extendedTypeID)
  +    {
  +
  +      int nsIndex = m_expandedNameTable.getNamespaceID(extendedTypeID);
  +      int lnIndex = m_expandedNameTable.getLocalNameID(extendedTypeID);
  +
  +      for (; ; ) 
  +      {
  +        int next = findElementFromIndex(nsIndex, lnIndex, nextPotential);
  +
  +        if (NOTPROCESSED != next)
  +        {
  +          int parent = m_parent[next];
  +          
  +          // Is it a child?
  +          if(parent == axisRoot)
  +            return next;
  +          
  +          // If the parent occured before the subtree root, then 
  +          // we know it is past the child axis.
  +          if(parent < axisRoot)
  +              return NULL;
  +          
  +          // Otherwise, it could be a descendant below the subtree root 
  +          // children, or it could be after the subtree root.  So we have 
  +          // to climb up until the parent is less than the subtree root, in 
  +          // which case we return NULL, or until it is equal to the subtree 
  +          // root, in which case we continue to look.
  +          do
  +          {
  +            parent = m_parent[parent];
  +            if(parent < axisRoot)
  +              return NULL;
  +          }
  +            while(parent > axisRoot);
  +          
  +          // System.out.println("Found node via index: "+first);
  +          nextPotential = next+1;
  +          continue;
  +        }
  +
  +        nextNode();
  +        
  +        if(!(m_nextsib[axisRoot] == NOTPROCESSED))
  +          break;
  +      }
  +
  +      return DTM.NULL;
  +    }
  +        
  +    /**
  +     * By the nature of the stateless traversal, the context node can not be
  +     * returned or the iteration will go into an infinate loop.  So to traverse 
  +     * an axis, the first function must be used to get the first node.
  +     *
  +     * <p>This method needs to be overloaded only by those axis that process
  +     * the self node. <\p>
  +     *
  +     * @param context The context node of this traversal. This is the point
  +     * that the traversal starts from.
  +     * @return the first node in the traversal.
  +     */
  +    public int first(int context)
  +    {
  +      return _firstch(context & m_mask) | m_dtmIdent;
  +    }
  +  
  +    /**
  +     * By the nature of the stateless traversal, the context node can not be
  +     * returned or the iteration will go into an infinate loop.  So to traverse 
  +     * an axis, the first function must be used to get the first node.
  +     *
  +     * <p>This method needs to be overloaded only by those axis that process
  +     * the self node. <\p>
  +     *
  +     * @param context The context node of this traversal. This is the point
  +     * of origin for the traversal -- its "root node" or starting point.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the first node in the traversal.
  +     */
  +    public int first(int context, int extendedTypeID)
  +    {
  +      if(true)
  +      {
  +        int identity = context & m_mask;
  +        
  +        int firstMatch = getNextIndexed(identity, _firstch(identity),
  +                                 extendedTypeID);
  +       
  +        return firstMatch | m_dtmIdent;
  +      }
  +      else
  +      {
  +        for (int current = _firstch(context & m_mask); 
  +             DTM.NULL != current; 
  +             current = _nextsib(current)) 
  +        {
  +          if (m_exptype[current] == extendedTypeID)
  +              return current | m_dtmIdent;
  +        }
  +        return NULL;
  +      }
  +    }
   
       /**
        * Traverse to the next node after the current node.
  @@ -337,10 +458,8 @@
        */
       public int next(int context, int current)
       {
  -
  -      // %OPT%
  -      return (context == current)
  -             ? getFirstChild(context) : getNextSibling(current);
  +      
  +      return _nextsib(current & m_mask) | m_dtmIdent;
       }
   
       /**
  @@ -355,17 +474,15 @@
        */
       public int next(int context, int current, int extendedTypeID)
       {
  -
  -      current = (context == current)
  -                ? getFirstChild(context) : getNextSibling(current);
   
  -      do
  +      for (current = _nextsib(current & m_mask); 
  +           DTM.NULL != current; 
  +           current = _nextsib(current)) 
         {
  -        if (m_exptype[current & m_mask] == extendedTypeID)
  -          return current;
  +        if (m_exptype[current] == extendedTypeID)
  +            return current | m_dtmIdent;
         }
  -      while (DTM.NULL != (current = getNextSibling(current)));
  -
  +      
         return NULL;
       }
     }
  @@ -1000,6 +1117,50 @@
      */
     private class ParentTraverser extends DTMAxisTraverser
     {
  +    /**
  +     * By the nature of the stateless traversal, the context node can not be
  +     * returned or the iteration will go into an infinate loop.  So to traverse 
  +     * an axis, the first function must be used to get the first node.
  +     *
  +     * <p>This method needs to be overloaded only by those axis that process
  +     * the self node. <\p>
  +     *
  +     * @param context The context node of this traversal. This is the point
  +     * that the traversal starts from.
  +     * @return the first node in the traversal.
  +     */
  +    public int first(int context)
  +    {
  +      return m_parent[context & m_mask] | m_dtmIdent;
  +    }
  +  
  +    /**
  +     * By the nature of the stateless traversal, the context node can not be
  +     * returned or the iteration will go into an infinate loop.  So to traverse 
  +     * an axis, the first function must be used to get the first node.
  +     *
  +     * <p>This method needs to be overloaded only by those axis that process
  +     * the self node. <\p>
  +     *
  +     * @param context The context node of this traversal. This is the point
  +     * of origin for the traversal -- its "root node" or starting point.
  +     * @param extendedTypeID The extended type ID that must match.
  +     *
  +     * @return the first node in the traversal.
  +     */
  +    public int first(int current, int extendedTypeID)
  +    {
  +      current = current & m_mask;
  +
  +      while (NULL != (current = m_parent[current]))
  +      {
  +        if (m_exptype[current] == extendedTypeID)
  +          return (current | m_dtmIdent);
  +      }
  +
  +      return NULL;
  +    }
  +
   
       /**
        * Traverse to the next node after the current node.
  @@ -1012,11 +1173,10 @@
       public int next(int context, int current)
       {
   
  -      if (context == current)
  -        return m_parent[current & m_mask] | m_dtmIdent;
  -      else
  -        return NULL;
  +      return NULL;
       }
  +    
  +
   
       /**
        * Traverse to the next node after the current node that is matched
  @@ -1031,17 +1191,6 @@
       public int next(int context, int current, int extendedTypeID)
       {
   
  -      if (context != current)
  -        return NULL;
  -
  -      current = current & m_mask;
  -
  -      while (NULL != (current = m_parent[current]))
  -      {
  -        if (m_exptype[current] == extendedTypeID)
  -          return (current | m_dtmIdent);
  -      }
  -
         return NULL;
       }
     }
  @@ -1430,7 +1579,7 @@
      * A non-xpath axis, returns all nodes that aren't namespaces or attributes,
      * from and including the root.
      */
  -  private class DescendantFromRootTraverser extends DescendantTraverser
  +  private class DescendantOrSelfFromRootTraverser extends DescendantTraverser
     {
   
       /**
  @@ -1468,4 +1617,48 @@
         return getDocument();
       }
     }
  +  
  +  /**
  +   * A non-xpath axis, returns all nodes that aren't namespaces or attributes,
  +   * from but not including the root.
  +   */
  +  private class DescendantFromRootTraverser extends DescendantTraverser
  +  {
  +
  +    /**
  +     * Get the first potential identity that can be returned, which is the axis 
  +     * root context in this case.
  +     *
  +     * @param identity The node identity of the root context of the traversal.
  +     *
  +     * @return The identity argument.
  +     */
  +    protected int getFirstPotential(int identity)
  +    {
  +      return _firstch(0);
  +    }
  +
  +    /**
  +     * Get the first potential identity that can be returned.
  +     * @param handle handle to the root context.
  +     * @return identity of the root of the subtree.
  +     */
  +    protected int getSubtreeRoot(int handle)
  +    {
  +      return 0;
  +    }
  +
  +    /**
  +     * Return the root.
  +     *
  +     * @param context The context node of this traversal.
  +     *
  +     * @return the first node in the traversal.
  +     */
  +    public int first(int context)
  +    {
  +      return _firstch(0) | m_dtmIdent;
  +    }
  +  }
  +
   }
  
  
  
  1.1.2.7   +39 -26    xml-xalan/java/src/org/apache/xml/dtm/ref/Attic/DTMManagerDefault.java
  
  Index: DTMManagerDefault.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/Attic/DTMManagerDefault.java,v
  retrieving revision 1.1.2.6
  retrieving revision 1.1.2.7
  diff -u -r1.1.2.6 -r1.1.2.7
  --- DTMManagerDefault.java	2001/06/04 07:47:20	1.1.2.6
  +++ DTMManagerDefault.java	2001/06/11 20:16:38	1.1.2.7
  @@ -103,22 +103,31 @@
      * Vector of DTMs that this manager manages. 
      */
     protected DTM m_dtms[] = new DTM[4095];
  -  
  +    
     /**
  -   * The first free DTM slot.  Keep this at 1 so that 0 never gets used 
  -   * as a DTM identity, which will avoid bugs with the DTM identity not 
  -   * getting set on a node handle.
  -   */
  -  protected int m_dtmsFirstFree = 1;
  -  
  -  /**
      * Add a DTM to the DTM table.
      * 
      * @param dtm Should be a valid reference to a DTM.
  +   */
  +  public void addDTM(DTM dtm, int id)
  +  {
  +    m_dtms[id] = dtm;
  +  }
  +  
  +  /**
  +   * Get the first free DTM ID available.
      */
  -  public void addDTM(DTM dtm)
  +  public int getFirstFreeDTMID()
     {
  -    m_dtms[m_dtmsFirstFree++] = dtm;
  +    int n = m_dtms.length;
  +    for (int i = 1; i < n; i++) 
  +    {
  +      if(null == m_dtms[i])
  +      {
  +        return i;
  +      }
  +    }
  +    throw new DTMException("No more DTM IDs are available!");
     }
     
     /**
  @@ -168,14 +177,15 @@
       if(DEBUG && null != source)
         System.out.println("Starting source: "+source.getSystemId());
       XMLStringFactory xstringFactory = m_xsf;
  -    int documentID = m_dtmsFirstFree << 20;
  +    int dtmPos = getFirstFreeDTMID();
  +    int documentID = dtmPos << 20;
   
       if ((null != source) && source instanceof DOMSource)
       {
         DOM2DTM dtm = new DOM2DTM(this, (DOMSource) source, documentID,
                                   whiteSpaceFilter, xstringFactory, doIndexing);
   
  -      addDTM(dtm);
  +      addDTM(dtm, dtmPos);
   
         if (DUMPTREE)
         {
  @@ -231,7 +241,7 @@
   
           // Go ahead and add the DTM to the lookup table.  This needs to be 
           // done before any parsing occurs.
  -        addDTM(dtm);
  +        addDTM(dtm, dtmPos);
   
           boolean haveXercesParser =
             (null != reader)
  @@ -240,7 +250,7 @@
           if (haveXercesParser)
             incremental = true;  // No matter what.  %REVIEW%
   
  -        if (true && incremental)
  +        if (false && incremental)
           {
   
             // Create a CoroutineManager to manage the coordination between the 
  @@ -422,15 +432,17 @@
         // subtree, but that's going to entail additional work
         // checking more DTMs... and getHandleFromNode is not a
         // cheap operation in most implementations.
  -      for(int i=m_dtmsFirstFree-1;i>=0;--i)
  +      // [I had to change this to look forward... sorry.  -sb]
  +      int max = m_dtms.length;
  +      for(int i = 0; i < max; i++)
           {
             DTM thisDTM=m_dtms[i];
  -          if(thisDTM instanceof DOM2DTM)
  -            {
  -              int handle=((DOM2DTM)thisDTM).getHandleOfNode(node);
  -              if(handle!=DTM.NULL) return handle;
  -            }
  -        }
  +          if((null != thisDTM) && thisDTM instanceof DOM2DTM)
  +          {
  +            int handle=((DOM2DTM)thisDTM).getHandleOfNode(node);
  +            if(handle!=DTM.NULL) return handle;
  +          }
  +         }
         
         // Fallback: Not found in one we know how to search.
         // Current solution: Generate a new DOM2DTM with this node as root.
  @@ -539,20 +551,21 @@
     }
   
     /**
  -   * NEEDSDOC Method getDTMIdentity
  +   * Given a DTM, find it's ID number in the DTM list.
      *
      *
  -   * NEEDSDOC @param dtm
  +   * @param dtm The DTM reference in question.
      *
  -   * NEEDSDOC (getDTMIdentity) @return
  +   * @return The ID, or -1 if not found in the list.
      */
     public int getDTMIdentity(DTM dtm)
     {
   
       // A backwards search should normally be the fastest.
  -    int n = m_dtmsFirstFree;
  +    // [But we can't do it... sorry.  -sb]
  +    int n = m_dtms.length;
   
  -    for (int i = (n - 1); i >= 0; i--)
  +    for (int i = 0; i < n; i++) 
       {
         DTM tdtm = m_dtms[i];
   
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.8   +0 -4      xml-xalan/java/src/org/apache/xml/dtm/ref/sax2dtm/Attic/SAX2DTM.java
  
  Index: SAX2DTM.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/sax2dtm/Attic/SAX2DTM.java,v
  retrieving revision 1.1.2.7
  retrieving revision 1.1.2.8
  diff -u -r1.1.2.7 -r1.1.2.8
  --- SAX2DTM.java	2001/06/11 19:26:17	1.1.2.7
  +++ SAX2DTM.java	2001/06/11 20:16:39	1.1.2.8
  @@ -1664,10 +1664,6 @@
   
       for (int i = startDecls; i < nDecls; i += 2)
       {
  -      // %TBD% JJK OUCH! We're explicitly reasserting the prefixes on every
  -      // element. That is NOT USEFUL given that both Scott and Joe implemented
  -      // search-the-parents logic and we're supposedly trying to distinguish
  -      // inherited from local.
         prefix = (String) m_prefixMappings.elementAt(i);
   
         if (prefix == null)
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.11.2.1  +18 -4     xml-xalan/java/src/org/apache/xpath/Arg.java
  
  Index: Arg.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/Arg.java,v
  retrieving revision 1.11
  retrieving revision 1.11.2.1
  diff -u -r1.11 -r1.11.2.1
  --- Arg.java	2001/03/07 04:27:18	1.11
  +++ Arg.java	2001/06/11 20:16:41	1.11.2.1
  @@ -80,7 +80,7 @@
      *
      * @return QName object containing the qualified name
      */
  -  public QName getQName()
  +  public final QName getQName()
     {
       return m_qname;
     }
  @@ -90,7 +90,7 @@
      *
      * @param name QName object representing the new Qualified Name.
      */
  -  public void setQName(QName name)
  +  public final void setQName(QName name)
     {
       m_qname = name;
     }
  @@ -107,7 +107,7 @@
      * @return the argument's stored XObject value.
      * @see #setVal(XObject)
      */
  -  public XObject getVal()
  +  public final XObject getVal()
     {
       return m_val;
     }
  @@ -118,10 +118,24 @@
      * @param val an XObject representing the arguments's value.
      * @see #getVal()
      */
  -  public void setVal(XObject val)
  +  public final void setVal(XObject val)
     {
       m_val = val;
     }
  +  
  +  /**
  +   * Have the object release it's resources.
  +   * Call only when the variable or argument is going out of scope.
  +   */
  +  public void detach()
  +  {
  +    if(null != m_val)
  +    {
  +      m_val.allowDetachToRelease(true);
  +      m_val.detach();
  +    }
  +  }
  +
   
     /** Field m_expression: Stored expression value of this argument.
      * @see #setExpression
  
  
  
  1.14.2.6  +51 -0     xml-xalan/java/src/org/apache/xpath/Expression.java
  
  Index: Expression.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/Expression.java,v
  retrieving revision 1.14.2.5
  retrieving revision 1.14.2.6
  diff -u -r1.14.2.5 -r1.14.2.6
  --- Expression.java	2001/06/04 07:52:56	1.14.2.5
  +++ Expression.java	2001/06/11 20:16:41	1.14.2.6
  @@ -70,6 +70,7 @@
   
   import org.apache.xml.utils.SAXSourceLocator;
   import org.apache.xml.utils.PrefixResolver;
  +import org.apache.xml.utils.XMLString;
   import org.apache.xml.dtm.DTMIterator;
   import org.apache.xml.dtm.DTM;
   
  @@ -178,6 +179,44 @@
       throws javax.xml.transform.TransformerException;
       
     /**
  +   * Evaluate expression to a number.
  +   *
  +   * @return 0.0
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public double num(XPathContext xctxt) 
  +    throws javax.xml.transform.TransformerException
  +  {
  +
  +    return execute(xctxt).num();
  +  }
  +
  +  /**
  +   * Evaluate expression to a boolean.
  +   *
  +   * @return false
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public boolean bool(XPathContext xctxt) 
  +    throws javax.xml.transform.TransformerException
  +  {
  +    return execute(xctxt).bool();
  +  }
  +
  +  /**
  +   * Cast result object to a string.
  +   *
  +   * @return The string this wraps or the empty string if null
  +   */
  +  public XMLString xstr(XPathContext xctxt)
  +    throws javax.xml.transform.TransformerException
  +  {
  +    return execute(xctxt).xstr();
  +  }
  +    
  +  /**
      * Tell if the expression is a nodeset expression.  In other words, tell 
      * if you can execute {@link asNode() asNode} without an exception.
      * @return true if the expression can be represented as a nodeset.
  @@ -247,6 +286,18 @@
       XObject obj = execute(xctxt);
       obj.dispatchCharactersEvents(handler);
     }
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public abstract void fixupVariables(java.util.Vector vars, int globalsSize);
   
   
     /**
  
  
  
  1.28.2.1  +227 -346  xml-xalan/java/src/org/apache/xpath/VariableStack.java
  
  Index: VariableStack.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/VariableStack.java,v
  retrieving revision 1.28
  retrieving revision 1.28.2.1
  diff -u -r1.28 -r1.28.2.1
  --- VariableStack.java	2001/03/14 09:11:38	1.28
  +++ VariableStack.java	2001/06/11 20:16:42	1.28.2.1
  @@ -56,33 +56,19 @@
    */
   package org.apache.xpath;
   
  -import java.util.Stack;
  -import java.util.Vector;
  -
  -import org.apache.xml.utils.QName;
  -import org.apache.xml.utils.IntStack;
   import org.apache.xpath.XPathContext;
   import org.apache.xpath.objects.XObject;
  -import org.apache.xpath.objects.XRTreeFrag;
  -
  -import org.w3c.dom.DocumentFragment;
  -import org.w3c.dom.Element;
  -import org.w3c.dom.Node;
  -
   import javax.xml.transform.TransformerException;
   
   /**
    * <meta name="usage" content="internal"/>
    * Defines a class to keep track of a stack for
  - * template arguments and variables.  The VariableStack extends 
  - * Stack, and each element in the stack is a stack frame, i.e. a 
  - * Stack itself.  The zero element is the global stack frame.
  - *
  - * Note: Someone recently made the suggestion that the
  - * globals should not be kept at the bottom of the stack,
  - * but should be implemented in a hash table.
  + * template arguments and variables.
  + * 
  + * <p>This has been changed from the previous incarnations of this 
  + * class to be fairly low level.</p>
    */
  -public class VariableStack extends Stack
  +public final class VariableStack implements Cloneable
   {
   
     /**
  @@ -90,431 +76,326 @@
      */
     public VariableStack()
     {
  -    pushContextMarker();
  +    reset();
     }
  -  
  -//  /**
  -//   * Pushes an item onto the top of this stack. This has exactly 
  -//   * the same effect as:
  -//   * <blockquote><pre>
  -//   * addElement(item)</pre></blockquote>
  -//   *
  -//   * @param   item   the item to be pushed onto this stack.
  -//   * @return  the <code>item</code> argument.
  -//   * @see     java.util.Vector#addElement
  -//   */
  -//  public Object push(Object item) 
  -//  {
  -//      if(!(item instanceof Stack))
  -//        throw new RuntimeException("You can only push a Stack on the variable stack!");
  -//
  -//      return super.push(item);
  -//  }
  -//  
  -//  public synchronized void addElement(Object obj) {
  -//    if(!(obj instanceof Stack))
  -//      throw new RuntimeException("You can only push a Stack on the variable stack!");
  -//      
  -//    super.addElement(obj);
  -//  }
  -//  
  -//  public synchronized void insertElementAt(Object obj, int index) {
  -//  if(!(obj instanceof Stack))
  -//    throw new RuntimeException("You can only push a Stack on the variable stack!");
  -//    
  -//  super.insertElementAt(obj, index);
  -//  }
  -//
  -//  public synchronized void setElementAt(Object obj, int index) {
  -//  if(!(obj instanceof Stack))
  -//    throw new RuntimeException("You can only push a Stack on the variable stack!");
  -//    
  -//  super.insertElementAt(obj, index);
  -// }
  -  
  +
     /**
  -   * Set where to start the current search for a variable.
  -   * If this is -1, the search should start at the top 
  -   * of the stack.
  -   * 
  -   * @param startPos The position to start the search, or -1
  -   * if the search should start from the top.
  +   * Returns a clone of this variable stack.
  +   *
  +   * @return  a clone of this variable stack.
  +   *
  +   * @throws CloneNotSupportedException
      */
  -  public void setSearchStart(int startPos)
  +  public synchronized Object clone() throws CloneNotSupportedException
     {
  -    m_searchStart = startPos;
  +
  +    VariableStack vs = (VariableStack) super.clone();
  +
  +    // I *think* I can get away with a shallow clone here?
  +    vs._sf = (XObject[]) _sf.clone();
  +    vs._links = (int[]) _links.clone();
  +
  +    return vs;
     }
  -  
  +
     /**
  -   * Get the position from where the search should start, 
  -   * which is either the searchStart property, or the top
  -   * of the stack if that value is -1.
  -   * 
  -   * @return The position from where the search should start, which
  -   * is always greater than or equal to zero.
  +   * The stack frame where all variables and params will be kept.
  +   * @serial
      */
  -  public int getSearchStartOrTop()
  -  {
  -    return (-1 == m_searchStart) ? this.size()-1 : m_searchStart;
  -  }
  -  
  +  XObject[] _sf = new XObject[XPathContext.RECURSIONLIMIT * 2];
  +
     /**
  -   * Get the position to start the search, or -1
  -   * if the search should start from the top.
  -   * 
  -   * @return The position to start the search, or -1
  -   * if the search should start from the top.
  +   * The top of the stack frame (<code>_sf</code>).
  +   * @serial
      */
  -  public int getSearchStart()
  -  {
  -    return m_searchStart;
  -  }
  +  int _top;
   
     /**
  -   * Mark the top of the global stack frame.
  +   * The bottom index of the current frame (relative to <code>_sf</code>).
  +   * @serial
      */
  -  public void markGlobalStackFrame()
  -  {
  -    m_globalStackFrameIndex = this.size();
  -  }
  +  private int _cfb;
   
     /**
  -   * Push a context marker onto the contextPositions stack to let us know when
  -   * to stop searching for a var.  This operation 
  -   * usually corresponds to the start of a template.
  +   * The stack of frame positions.  I call 'em links because of distant 
  +   * <a href="http://math.millikin.edu/mprogers/Courses/currentCourses/CS481-ComputerArchitecture/cs481.Motorola68000.html">
  +   * Motorola 68000 assembler</a> memories.  :-)
  +   * @serial
      */
  -  public void pushContextPosition(int pos)
  -  {
  -    // m_contextPositions.push(pos);
  -  }
  -  
  +  int[] _links = new int[XPathContext.RECURSIONLIMIT];
  +
  +  /**
  +   * The top of the links stack.
  +   */
  +  int _linksTop;
  +
     /**
  -   * Pop the current context position onto the contextPositions. This operation 
  -   * usually corresponds to the ending of a template.
  +   * Get the element at the given index, regardless of stackframe.
  +   *
  +   * @param i index from zero.
  +   *
  +   * @return The item at the given index.
      */
  -  public void popContextPosition()
  +  public final XObject elementAt(final int i)
     {
  -    // m_contextPositions.pop();
  +    return _sf[i];
     }
  -  
  +
     /**
  -   * Get the current context position.
  -   * 
  -   * @return The context marker into the stack to let us know when
  -   * to stop searching for a var.
  +   * Get size of the stack.
  +   *
  +   * @return the total size of the execution stack.
      */
  -  public int getContextPos()
  +  public final int size()
     {
  -    // return m_contextPositions.peek();
  -    return this.size()-1;
  +    return _top;
     }
     
     /**
  -   * Push the current top of the stack as 
  -   * a context marker into the variables stack to let us know when
  -   * to stop searching for a var.  This operation 
  -   * usually corresponds to the start of a template.
  +   * Reset the stack to a start position.
  +   *
  +   * @return the total size of the execution stack.
      */
  -  public void pushContextMarker()
  +  public final void reset()
     {
  -    // m_contextPositions.push(this.size());
  -    push(m_emptyStackFrame);
  +    _top = 0;
  +    _linksTop = 0;
  +
  +    // Adding one here to the stack of frame positions will allow us always 
  +    // to look one under without having to check if we're at zero.
  +    // (As long as the caller doesn't screw up link/unlink.)
  +    _links[_linksTop++] = 0;
     }
   
     /**
  -   * Pop the current context from the current context stack.
  +   * Set the current stack frame.
  +   *
  +   * @param sf The new stack frame position.
      */
  -  public void popCurrentContext()
  +  public final void setStackFrame(int sf)
     {
  -
  -    // int newSize = m_contextPositions.pop();
  -
  -    // setSize(newSize);
  -    pop();
  +    _cfb = sf;
     }
  -  
  +
     /**
  -   * Get the current stack frame.
  -   * 
  -   * @return non-null reference to current stack frame, which may be 
  -   * the global stack.
  +   * Get the position from where the search should start,
  +   * which is either the searchStart property, or the top
  +   * of the stack if that value is -1.
  +   *
  +   * @return The current stack frame position.
      */
  -   private Stack getCurrentFrame()
  -   {
  -      int stackFrameIndex = (-1 == m_searchStart) ? this.size()-1 : m_searchStart;
  -      // System.out.println("what: "+this.elementAt(stackFrameIndex));
  -      return (Stack)elementAt(stackFrameIndex);
  -   }
  -   
  -  /**
  -   * Allocate variables frame.
  -   */
  -   private Stack allocateCurrentFrame()
  -   {
  -      int stackFrameIndex = (-1 == m_searchStart) ? this.size()-1 : m_searchStart;
  -      Stack newFrame = new Stack();
  -      this.setElementAt(newFrame, stackFrameIndex);
  -      return newFrame;
  -   }
  +  public final int getStackFrame()
  +  {
  +    return _cfb;
  +  }
   
  -  
     /**
  -   * Push a parameter onto the stack, or replace it 
  -   * if it already exists.  Don't forget
  -   * to call startContext before pushing a series of
  -   * arguments for a given macro call.
  +   * Allocates memory (called a stackframe) on the stack; used to store 
  +   * local variables and parameter arguments.
  +   * 
  +   * <p>I use the link/unlink concept because of distant 
  +   * <a href="http://math.millikin.edu/mprogers/Courses/currentCourses/CS481-ComputerArchitecture/cs481.Motorola68000.html">
  +   * Motorola 68000 assembler</a> memories.</p>
      *
  -   * @param qname The qualified name of the variable.
  -   * @param val The wrapped value of the variable.
  +   * @param size The size of the stack frame allocation.  This ammount should 
  +   * normally be the maximum number of variables that you can have allocated 
  +   * at one time in the new stack frame.
  +   *
  +   * @return The bottom of the stack frame, from where local variable addressing 
  +   * should start from.
      */
  -  public void pushOrReplaceParameter(QName qname, XObject xval)
  +  public final int link(final int size)
     {
  -    Stack frame = getCurrentFrame();
  -    if(frame == m_emptyStackFrame)
  +
  +    _cfb = _top;
  +    _top += size;
  +
  +    if (_top >= _sf.length)
       {
  -      frame = allocateCurrentFrame();
  +      XObject newsf[] = new XObject[_sf.length + (1024 * 4) + size];
  +
  +      System.arraycopy(_sf, 0, newsf, 0, _sf.length);
  +
  +      _sf = newsf;
       }
  -    for (int i = (frame.size() - 1); i >= 0; i--)
  +
  +    if (_linksTop+1 >= _links.length)
       {
  -      Arg arg = (Arg)frame.elementAt(i);
  -      if(arg.getQName().equals(qname) && arg.isFromWithParam())
  -      {
  -        frame.setElementAt(new Arg(qname, xval, true), i);
  -        return;
  -      }
  +      int newlinks[] = new int[_links.length + (1024 * 2)];
  +
  +      System.arraycopy(_links, 0, newlinks, 0, _links.length);
  +
  +      _links = newlinks;
       }
  -    frame.push(new Arg(qname, xval, true));
  +
  +    _links[_linksTop++] = _cfb;
  +
  +    return _cfb;
     }
  -  
  +
     /**
  -   * Re-mark the variables in the current frame as all 
  -   * being parameters.
  +   * Free up the stack frame that was last allocated with 
  +   * {@link link(int size)}.
      */
  -  public void remarkParams()
  +  public final void unlink()
     {
  -    Stack frame = getCurrentFrame();
  -    
  -    for (int i = (frame.size() - 1); i >= 0; i--)
  -    {
  -      Arg arg = (Arg)frame.elementAt(i);
  -      if(null != arg)
  -        arg.setIsVisible(false);
  -    }
  +    _top = _links[--_linksTop];
  +    _cfb = _links[_linksTop - 1];
     }
   
  -
     /**
  -   * Push an argument onto the stack.  Don't forget
  -   * to call startContext before pushing a series of
  -   * arguments for a given macro call.
  -   *
  -   * @param qname The qualified name of the variable.
  -   * @param val The wrapped value of the variable.
  -   */
  -  // Note that this method will push an Arg onto the Frame even
  -  // if an Arg for this qname already exists, effectively hiding that 
  -  // previous stack entry.  That entry is never reclaimed.  This could lead to
  -  // objects in the Frame that will never be used.  Hopefully, this situation
  -  // will be short lived since the frame is released after the node-set is
  -  // in the apply-templates is completed.  However, for large node-sets, we
  -  // will be putting a lot of unusable entries in the Frame.  If this becomes
  -  // a problem, we should replace those matching entries provided that 
  -  // isFromWithParam is false.  I'm not sure that the overhead of searching
  -  // for matching entries is worth it at this point.  GLP
  -  public void pushVariable(QName qname, XObject val)
  -  {
  -    Stack frame = getCurrentFrame();
  -    if(frame == m_emptyStackFrame)
  -      frame = allocateCurrentFrame();
  -    frame.push(new Arg(qname, val, false));
  +   * Set a local variable or parameter in the current stack frame.
  +   *
  +   *
  +   * @param index Local variable index relative to the current stack 
  +   * frame bottom.
  +   * 
  +   * @param val The value of the variable that is being set.
  +   */
  +  public final void setLocalVariable(int index, XObject val)
  +  {
  +    _sf[index+_cfb] = val;
     }
  -  
  +
     /**
  -   * Push an argument onto the stack.  Don't forget
  -   * to call startContext before pushing a series of
  -   * arguments for a given macro call.
  -   *
  -   * @param arg The variable argument.
  -   */
  -  public void pushVariableArg(Arg arg)
  -  {
  -    Stack frame = getCurrentFrame();
  -    if(frame == m_emptyStackFrame)
  -      frame = allocateCurrentFrame();
  -    frame.push(arg);
  +   * Set a local variable or parameter in the specified stack frame.
  +   *
  +   *
  +   * @param index Local variable index relative to the current stack 
  +   * frame bottom.
  +   * 
  +   * @param val The value of the variable that is being set.
  +   */
  +  public final void setLocalVariable(int index, XObject val, int stackFrame)
  +  {
  +    _sf[index+stackFrame] = val;
     }
   
  -  
     /**
  -   * Returns a variable or parameter that is already declared, 
  -   * either in the current context or in the global space.
  +   * Get a local variable or parameter in the current stack frame.
      *
  -   * @param qname The qualified name of the variable.
      *
  -   * @return the Arg if the variable is already declared, otherwise <code>null</code>.
  +   * @param xctxt The XPath context, which must be passed in order to 
  +   * lazy evaluate variables.
  +   * 
  +   * @param index Local variable index relative to the current stack 
  +   * frame bottom.
      *
  +   * @return The value of the variable.
  +   *
      * @throws TransformerException
      */
  -  public Arg getDeclaredVariable(QName qname) throws TransformerException
  +  public final XObject getLocalVariable(XPathContext xctxt, int index)
  +          throws TransformerException
     {
   
  -    Stack frame = getCurrentFrame();
  -    
  -    for (int i = (frame.size() - 1); i >= 0; i--)
  -    {
  -      Object obj = frame.elementAt(i);
  +    index += _cfb;
   
  -      if (((Arg) obj).getQName().equals(qname))
  -      {
  -        return (Arg) obj;
  -      }
  -    }
  -          
  -    Stack gframe = (Stack)this.elementAt(0);
  -    if(gframe == frame)
  -      return null;
  -    
  -    for (int i = (gframe.size() - 1); i >= 0; i--)
  -    {
  -      Object obj = gframe.elementAt(i);
  +    XObject val = _sf[index];
   
  -      if (((Arg) obj).getQName().equals(qname))
  -      {
  -        return (Arg) obj;
  -      }
  -    }
  +    // Lazy execution of variables.
  +    if (val.getType() == XObject.CLASS_UNRESOLVEDVARIABLE)
  +      return (_sf[index] = val.execute(xctxt));
   
  -    return null;
  +    return val;
     }
  -
  -
  +  
     /**
  -   * Get the variable argument.
  +   * Get a local variable or parameter in the current stack frame.
  +   *
      *
  -   * @param qname The qualified name of the variable.
  +   * @param index Local variable index relative to the given 
  +   * frame bottom.
      *
  -   * @return the argument object.
  +   * @return The value of the variable.
      *
      * @throws TransformerException
      */
  -  public Arg getParamArg(QName qname) throws TransformerException
  +  public final XObject getLocalVariable(int index, int frame)
  +          throws TransformerException
     {
   
  -    XObject val = null;
  -    Stack frame = getCurrentFrame();
  -    
  -    for (int i = (frame.size() - 1); i >= 0; i--)
  -    {
  -      Arg arg = (Arg)frame.elementAt(i);
  +    index += frame;
   
  -      if (arg.getQName().equals(qname) && arg.isFromWithParam())
  -      {
  -        return arg;
  -      }
  -    }
  +    XObject val = _sf[index];
   
  -    return null;
  +    return val;
     }
  -
  +  
     /**
  -   * Given a name, return an object representing
  -   * the value.
  +   * Tell if a local variable has been set or not.
      *
  -   * @param qname The qualified name of the variable.
  +   * @param index Local variable index relative to the current stack 
  +   * frame bottom.
      *
  -   * @return The wrapped value of the variable.
  +   * @return true if the value at the index is not null.
      *
      * @throws TransformerException
      */
  -  public XObject getVariable(XPathContext xctxt, QName name) throws TransformerException
  +  public final boolean isLocalSet(int index)
  +          throws TransformerException
     {
  -
  -    Stack frame = getCurrentFrame();
  -    Stack gframe = (Stack)this.elementAt(0);
       
  -    if(frame != gframe)
  -    {
  -      for (int i = (frame.size() - 1); i >= 0; i--)
  -      {
  -        Arg arg = (Arg)frame.elementAt(i);
  +    return (_sf[index + _cfb] != null);
  +  }
     
  -        if (arg.getQName().equals(name) && arg.isVisible())
  -        {
  -          XObject val = arg.getVal();
  -          if(val.getType() == XObject.CLASS_UNRESOLVEDVARIABLE)
  -          {
  -            val = val.execute(xctxt);
  -            arg.setVal(val);
  -          }
  -          return val;
  -        }
  -      }
  -    }
  -     
  -    for (int i = (gframe.size() - 1); i >= 0; i--)
  -    {
  -      Arg arg = (Arg)gframe.elementAt(i);
  -
  -      if (arg.getQName().equals(name) && arg.isVisible())
  -      {
  -        XObject val = arg.getVal();
  -        if(val.getType() == XObject.CLASS_UNRESOLVEDVARIABLE)
  -        {
  -          val = val.execute(xctxt);
  -          arg.setVal(val);
  -        }
  -        return val;
  -      }
  -    }
  -
  -    return null;
  +  private static XObject[] m_nulls = new XObject[1024];
  +  
  +  /**
  +   * Use this to clear the variables in a section of the stack.  This is 
  +   * used to clear the parameter section of the stack, so that default param 
  +   * values can tell if they've already been set.  It is important to note that 
  +   * this function has a 1K limitation.
  +   * 
  +   * @param start The start position, relative to the current local stack frame.
  +   * @param len The number of slots to be cleared.
  +   */
  +  public final void clearLocalSlots(int start, int len)
  +  {
  +    start+=_cfb;
  +    System.arraycopy(m_nulls, 0, _sf, start, len);
     }
  -
  +  
     /**
  -   * Push an argument onto the stack.  Don't forget
  -   * to call startContext before pushing a series of
  -   * arguments for a given macro call.
  +   * Set a global variable or parameter in the global stack frame.
  +   *
  +   *
  +   * @param index Local variable index relative to the global stack frame 
  +   * bottom.
  +   * 
  +   * @param val The value of the variable that is being set.
      */
  -  public void pushElemFrame()
  +  public final void setGlobalVariable(final int index, final XObject val)
     {
  -    Stack frame = getCurrentFrame();
  -
  -    m_elemFramePos.push(frame.size());
  +    _sf[index] = val;
     }
   
     /**
  -   * Pop the current context from the current context stack.
  +   * Get a global variable or parameter from the global stack frame.
  +   *
  +   *
  +   * @param xctxt The XPath context, which must be passed in order to 
  +   * lazy evaluate variables.
  +   * 
  +   * @param index Global variable index relative to the global stack 
  +   * frame bottom.
  +   *
  +   * @return The value of the variable.
  +   *
  +   * @throws TransformerException
      */
  -  public void popElemFrame()
  +  public final XObject getGlobalVariable(XPathContext xctxt, final int index)
  +          throws TransformerException
     {
   
  -    Stack frame = getCurrentFrame();
  -    int newSize = m_elemFramePos.pop();
  +    XObject val = _sf[index];
   
  -    frame.setSize(newSize);
  -  }
  -  
  -  
  -  /**
  -   * Hold the position of the start of the current element frame.
  -   * @serial
  -   */
  -  private IntStack m_elemFramePos = new IntStack();
  -  
  -  /**
  -   * Hold the position of the start of the current element contexts.
  -   */
  -  private static final Stack m_emptyStackFrame = new Stack();
  +    // Lazy execution of variables.
  +    if (val.getType() == XObject.CLASS_UNRESOLVEDVARIABLE)
  +      return (_sf[index] = val.execute(xctxt));
   
  -  /** The top of the globals space.
  -   *  @serial     */
  -  private int m_globalStackFrameIndex = -1;
  +    return val;
  +  }
     
  -  /** Where to start the current search for a variable.
  -   * If this is -1, the search should start at the top 
  -   * of the stack.
  -   * @serial */
  -  private int m_searchStart = -1;
  -
  -}  // end XSLArgStack
  +}  // end VariableStack
   
  
  
  
  1.18.2.9  +91 -8     xml-xalan/java/src/org/apache/xpath/XPath.java
  
  Index: XPath.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/XPath.java,v
  retrieving revision 1.18.2.8
  retrieving revision 1.18.2.9
  diff -u -r1.18.2.8 -r1.18.2.9
  --- XPath.java	2001/06/08 19:02:09	1.18.2.8
  +++ XPath.java	2001/06/11 20:16:42	1.18.2.9
  @@ -114,6 +114,21 @@
     {
       return m_mainExp;
     }
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    m_mainExp.fixupVariables(vars, globalsSize);
  +  }
   
     /**
      * Set the raw expression object for this object.
  @@ -230,19 +245,17 @@
     {  
       this(exprString, locator, prefixResolver, type, null);    
     }
  -	
  -	/**
  -   * Construct an XPath object.  The object must be initialized by the
  -   * XPathParser.initXPath method.
  +
  +  /**
  +   * Construct an XPath object.
      *
  -   * @param exp The XPath expression.
  +   * @param expr The Expression object.
      *
      * @throws javax.xml.transform.TransformerException if syntax or other error.
      */
  -  public XPath(Expression exp)
  -            throws javax.xml.transform.TransformerException
  +  public XPath(Expression expr)
     {  
  -    this.setExpression(exp);    
  +    this.setExpression(expr);   
     }
     
     /**
  @@ -342,6 +355,76 @@
       }
   
       return xobj;
  +  }
  +  
  +  /**
  +   * <meta name="usage" content="experimental"/>
  +   * Given an expression and a context, evaluate the XPath
  +   * and return the result.
  +   * 
  +   * @param xctxt The execution context.
  +   * @param contextNode The node that "." expresses.
  +   * @param namespaceContext The context in which namespaces in the
  +   * XPath are supposed to be expanded.
  +   * 
  +   * @throws TransformerException thrown if the active ProblemListener decides
  +   * the error condition is severe enough to halt processing.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public boolean bool(
  +          XPathContext xctxt, int contextNode, PrefixResolver namespaceContext)
  +            throws javax.xml.transform.TransformerException
  +  {
  +
  +    xctxt.pushNamespaceContext(namespaceContext);
  +
  +    xctxt.pushCurrentNodeAndExpression(contextNode, contextNode);
  +
  +    try
  +    {
  +      return m_mainExp.bool(xctxt);
  +    }
  +    catch (TransformerException te)
  +    {
  +      te.setLocator(this.getLocator());
  +      ErrorListener el = xctxt.getErrorListener();
  +      if(null != el) // defensive, should never happen.
  +      {
  +        el.error(te);
  +      }
  +      else
  +        throw te;
  +    }
  +    catch (Exception e)
  +    {
  +      while (e instanceof org.apache.xml.utils.WrappedRuntimeException)
  +      {
  +        e = ((org.apache.xml.utils.WrappedRuntimeException) e).getException();
  +      }
  +      // e.printStackTrace();
  +
  +      String msg = e.getMessage();
  +      msg = (msg == null || msg.length()== 0)? "Unknown error in XPath" : msg;
  +      TransformerException te = new TransformerException(msg,
  +              getLocator(), e);
  +      ErrorListener el = xctxt.getErrorListener();
  +      // te.printStackTrace();
  +      if(null != el) // defensive, should never happen.
  +      {
  +        el.fatalError(te);
  +      }
  +      else
  +        throw te;
  +    }
  +    finally
  +    {
  +      xctxt.popNamespaceContext();
  +
  +      xctxt.popCurrentNodeAndExpression();
  +    }
  +
  +    return false;
     }
   
     /** Set to true to get diagnostic messages about the result of 
  
  
  
  1.20.2.15 +0 -16     xml-xalan/java/src/org/apache/xpath/XPathContext.java
  
  Index: XPathContext.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/XPathContext.java,v
  retrieving revision 1.20.2.14
  retrieving revision 1.20.2.15
  diff -u -r1.20.2.14 -r1.20.2.15
  --- XPathContext.java	2001/06/04 07:52:57	1.20.2.14
  +++ XPathContext.java	2001/06/11 20:16:42	1.20.2.15
  @@ -467,22 +467,6 @@
       m_variableStacks = varStack;
     }
   
  -  /**
  -   * Given a name, locate a variable in the current context, and return
  -   * the Object.
  -   *
  -   * @param qname The qualified name of a variable.
  -   *
  -   * @return reference to variable, or null if not found.
  -   *
  -   * @throws javax.xml.transform.TransformerException
  -   */
  -  public XObject getVariable(QName qname) throws javax.xml.transform.TransformerException
  -  {
  -
  -    return getVarStack().getVariable(this, qname);
  -  }
  -
     // ================ SourceTreeManager ===================
   
     /** The source tree manager, which associates Source objects to source 
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.8.2.5   +60 -15    xml-xalan/java/src/org/apache/xpath/axes/ChildTestIterator.java
  
  Index: ChildTestIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/ChildTestIterator.java,v
  retrieving revision 1.8.2.4
  retrieving revision 1.8.2.5
  diff -u -r1.8.2.4 -r1.8.2.5
  --- ChildTestIterator.java	2001/06/03 03:09:23	1.8.2.4
  +++ ChildTestIterator.java	2001/06/11 20:16:44	1.8.2.5
  @@ -62,13 +62,11 @@
   import org.apache.xpath.patterns.NodeTest;
   import org.apache.xpath.objects.XObject;
   
  -//import org.w3c.dom.Node;
  -//import org.w3c.dom.DOMException;
  -//import org.w3c.dom.traversal.NodeFilter;
  -//import org.w3c.dom.traversal.NodeIterator;
   import org.apache.xml.dtm.DTM;
   import org.apache.xml.dtm.DTMIterator;
   import org.apache.xml.dtm.DTMFilter;
  +import org.apache.xml.dtm.DTMAxisTraverser;
  +import org.apache.xml.dtm.Axis;
   
   /**
    * <meta name="usage" content="advanced"/>
  @@ -78,6 +76,12 @@
    */
   public class ChildTestIterator extends LocPathIterator
   {
  +  /** The traverser to use to navigate over the descendants. */
  +  transient protected DTMAxisTraverser m_traverser;
  +  
  +  /** The extended type ID, not set until setRoot. */
  +//  protected int m_extendedTypeID;
  +
   
     /**
      * Create a ChildTestIterator object.
  @@ -135,10 +139,21 @@
      * @return The next node on the axis, or DTM.NULL.
      */
     protected int getNextNode()
  -  {
  -    m_lastFetched = (DTM.NULL == m_lastFetched)
  -                     ? m_cdtm.getFirstChild(m_context)
  -                     : m_cdtm.getNextSibling(m_lastFetched);
  +  {                     
  +    if(true /* 0 == m_extendedTypeID */)
  +    {
  +      m_lastFetched = (DTM.NULL == m_lastFetched)
  +                   ? m_traverser.first(m_context)
  +                   : m_traverser.next(m_context, m_lastFetched);
  +    }
  +//    else
  +//    {
  +//      m_lastFetched = (DTM.NULL == m_lastFetched)
  +//                   ? m_traverser.first(m_context, m_extendedTypeID)
  +//                   : m_traverser.next(m_context, m_lastFetched, 
  +//                                      m_extendedTypeID);
  +//    }
  +
       return m_lastFetched;
     }
   
  @@ -180,15 +195,14 @@
       
       org.apache.xpath.VariableStack vars;
       int savedStart;
  -    if (-1 != m_varStackPos)
  +    if (-1 != m_stackFrame)
       {
         vars = m_execContext.getVarStack();
   
         // These three statements need to be combined into one operation.
  -      savedStart = vars.getSearchStart();
  +      savedStart = vars.getStackFrame();
   
  -      vars.setSearchStart(m_varStackPos);
  -      vars.pushContextPosition(m_varStackContext);
  +      vars.setStackFrame(m_stackFrame);
       }
       else
       {
  @@ -233,13 +247,44 @@
       }
       finally
       {
  -      if (-1 != m_varStackPos)
  +      if (-1 != m_stackFrame)
         {
           // These two statements need to be combined into one operation.
  -        vars.setSearchStart(savedStart);
  -        vars.popContextPosition();
  +        vars.setStackFrame(savedStart);
         }
       }
  +  }
  +  
  +  /**
  +   * Initialize the context values for this expression
  +   * after it is cloned.
  +   *
  +   * @param execContext The XPath runtime context for this
  +   * transformation.
  +   */
  +  public void setRoot(int context, Object environment)
  +  {
  +    super.setRoot(context, environment);
  +    m_traverser = m_cdtm.getAxisTraverser(Axis.CHILD);
  +    
  +//    String localName = getLocalName();
  +//    String namespace = getNamespace();
  +//    int what = m_whatToShow;
  +//    // System.out.println("what: ");
  +//    // NodeTest.debugWhatToShow(what);
  +//    if(DTMFilter.SHOW_ALL == what ||
  +//       ((DTMFilter.SHOW_ELEMENT & what) == 0)
  +//       || localName == NodeTest.WILD
  +//       || namespace == NodeTest.WILD)
  +//    {
  +//      m_extendedTypeID = 0;
  +//    }
  +//    else
  +//    {
  +//      int type = getNodeTypeTest(what);
  +//      m_extendedTypeID = m_cdtm.getExpandedTypeID(namespace, localName, type);
  +//    }
  +    
     }
   
   }
  
  
  
  1.8.2.11  +13 -10    xml-xalan/java/src/org/apache/xpath/axes/DescendantIterator.java
  
  Index: DescendantIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/DescendantIterator.java,v
  retrieving revision 1.8.2.10
  retrieving revision 1.8.2.11
  diff -u -r1.8.2.10 -r1.8.2.11
  --- DescendantIterator.java	2001/06/03 03:09:23	1.8.2.10
  +++ DescendantIterator.java	2001/06/11 20:16:45	1.8.2.11
  @@ -108,12 +108,17 @@
       {
         // %TBD% orSelf and fromRoot should be considered seperately.
         fromRoot = true;
  -      orSelf = true;
  +      // orSelf = true;
         firstStepPos += 8;
       }
       
       if(fromRoot)
  -      m_axis = Axis.DESCENDANTSFROMROOT;
  +    {
  +      if(orSelf)
  +        m_axis = Axis.DESCENDANTSORSELFFROMROOT;
  +      else
  +        m_axis = Axis.DESCENDANTSFROMROOT;
  +    }
       else if(orSelf)
         m_axis = Axis.DESCENDANTORSELF;
       else
  @@ -146,7 +151,7 @@
     public DescendantIterator()
     {
       super(null);
  -    m_axis = Axis.DESCENDANTSFROMROOT;
  +    m_axis = Axis.DESCENDANTSORSELFFROMROOT;
       int whatToShow = DTMFilter.SHOW_ALL;
       initNodeTest(whatToShow);
     }
  @@ -211,15 +216,14 @@
       
       org.apache.xpath.VariableStack vars;
       int savedStart;
  -    if (-1 != m_varStackPos)
  +    if (-1 != m_stackFrame)
       {
         vars = m_execContext.getVarStack();
   
         // These three statements need to be combined into one operation.
  -      savedStart = vars.getSearchStart();
  +      savedStart = vars.getStackFrame();
   
  -      vars.setSearchStart(m_varStackPos);
  -      vars.pushContextPosition(m_varStackContext);
  +      vars.setStackFrame(m_stackFrame);
       }
       else
       {
  @@ -276,11 +280,10 @@
       }
       finally
       {
  -      if (-1 != m_varStackPos)
  +      if (-1 != m_stackFrame)
         {
           // These two statements need to be combined into one operation.
  -        vars.setSearchStart(savedStart);
  -        vars.popContextPosition();
  +        vars.setStackFrame(savedStart);
         }
       }
     }
  
  
  
  1.14.2.8  +20 -5     xml-xalan/java/src/org/apache/xpath/axes/FilterExprWalker.java
  
  Index: FilterExprWalker.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/FilterExprWalker.java,v
  retrieving revision 1.14.2.7
  retrieving revision 1.14.2.8
  diff -u -r1.14.2.7 -r1.14.2.8
  --- FilterExprWalker.java	2001/06/03 03:09:23	1.14.2.7
  +++ FilterExprWalker.java	2001/06/11 20:16:45	1.14.2.8
  @@ -151,15 +151,13 @@
           VariableStack vars = m_lpi.m_execContext.getVarStack();
           
           // These three statements need to be combined into one operation.
  -        int savedStart = vars.getSearchStart();
  -        vars.setSearchStart(m_lpi.m_varStackPos);
  -        vars.pushContextPosition(m_lpi.m_varStackContext);
  +        int savedStart = vars.getStackFrame();
  +        vars.setStackFrame(m_lpi.m_stackFrame);
           
           obj = m_expr.execute(m_lpi.getXPathContext());
           
           // These two statements need to be combined into one operation.
  -        vars.setSearchStart(savedStart);
  -        vars.popContextPosition();
  +        vars.setStackFrame(savedStart);
         }
         else
           obj = m_expr.execute(m_lpi.getXPathContext());
  @@ -292,4 +290,21 @@
   
       // return m_lpi.getDOMHelper().getLevel(this.m_currentNode)+1;
     }
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    super.fixupVariables(vars, globalsSize);
  +    m_expr.fixupVariables(vars, globalsSize);
  +  }
  +
   }
  
  
  
  1.24.2.13 +35 -31    xml-xalan/java/src/org/apache/xpath/axes/LocPathIterator.java
  
  Index: LocPathIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/LocPathIterator.java,v
  retrieving revision 1.24.2.12
  retrieving revision 1.24.2.13
  diff -u -r1.24.2.12 -r1.24.2.13
  --- LocPathIterator.java	2001/06/04 21:25:51	1.24.2.12
  +++ LocPathIterator.java	2001/06/11 20:16:45	1.24.2.13
  @@ -268,17 +268,34 @@
     public int asNode(XPathContext xctxt)
       throws javax.xml.transform.TransformerException
     {
  -    LocPathIterator iter = (LocPathIterator)m_clones.getInstance();
  +    DTMIterator iter = (DTMIterator)m_clones.getInstance();
   
       int current = xctxt.getCurrentNode();
       
       iter.setRoot(current, xctxt);
   
       int next = iter.nextNode();
  -    m_clones.freeInstance(iter);
  +    // m_clones.freeInstance(iter);
  +    iter.detach();
       return next;
     }
  +  
  +  /**
  +   * Evaluate this operation directly to a boolean.
  +   *
  +   * @param xctxt The runtime execution context.
  +   *
  +   * @return The result of the operation as a boolean.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public boolean bool(XPathContext xctxt)
  +          throws javax.xml.transform.TransformerException
  +  {
  +    return (asNode(xctxt) != DTM.NULL);
  +  }
   
  +
     /**
      * <meta name="usage" content="advanced"/>
      * Set if this is an iterator at the upper level of
  @@ -329,12 +346,8 @@
   //    m_next = 0;
   
       if (m_isTopLevel)
  -    {
  -      VariableStack vars = xctxt.getVarStack();
  +      this.m_stackFrame = xctxt.getVarStack().getStackFrame();
   
  -      this.m_varStackPos = vars.getSearchStartOrTop();
  -      this.m_varStackContext = vars.getContextPos();
  -    }
       reset();
     }
   
  @@ -646,6 +659,19 @@
         m_clones.freeInstance(this);
       }
     }
  +  
  +  /**
  +   * Reset the iterator.
  +   */
  +  public void reset()
  +  {
  +
  +    // super.reset();
  +    m_foundLast = false;
  +    m_lastFetched = DTM.NULL;
  +    m_next = 0;
  +    m_last = 0;
  +  }
   
     /**
      * Get a cloned Iterator that is reset to the beginning
  @@ -682,19 +708,6 @@
   //  }
   
     /**
  -   * Reset the iterator.
  -   */
  -  public void reset()
  -  {
  -
  -    // super.reset();
  -    m_foundLast = false;
  -    m_lastFetched = DTM.NULL;
  -    m_next = 0;
  -    m_last = 0;
  -  }
  -
  -  /**
      *  Returns the next node in the set and advances the position of the
      * iterator in the set. After a NodeIterator is created, the first call
      * to nextNode() returns the first node in the set.
  @@ -942,19 +955,10 @@
      */
     transient protected DTM m_cdtm;
     
  -  /**
  -   * An index to the point in the variable stack where we should
  -   * begin variable searches for this iterator.
  -   * This is -1 if m_isTopLevel is false.
  -   */
  -  transient int m_varStackPos = -1;
  -
     /**
  -   * An index into the variable stack where the variable context
  -   * ends, i.e. at the point we should terminate the search and
  -   * go looking for global variables.
  +   * The stack frame index for this iterator.
      */
  -  transient int m_varStackContext;
  +  transient int m_stackFrame = -1;
   
     /**
      * Value determined at compile time, indicates that this is an
  
  
  
  1.1.2.5   +5 -7      xml-xalan/java/src/org/apache/xpath/axes/Attic/MatchPatternIterator.java
  
  Index: MatchPatternIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/Attic/MatchPatternIterator.java,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- MatchPatternIterator.java	2001/06/03 03:09:23	1.1.2.4
  +++ MatchPatternIterator.java	2001/06/11 20:16:46	1.1.2.5
  @@ -249,15 +249,14 @@
       
       org.apache.xpath.VariableStack vars;
       int savedStart;
  -    if (-1 != m_varStackPos)
  +    if (-1 != m_stackFrame)
       {
         vars = m_execContext.getVarStack();
   
         // These three statements need to be combined into one operation.
  -      savedStart = vars.getSearchStart();
  +      savedStart = vars.getStackFrame();
   
  -      vars.setSearchStart(m_varStackPos);
  -      vars.pushContextPosition(m_varStackContext);
  +      vars.setStackFrame(m_stackFrame);
       }
       else
       {
  @@ -310,11 +309,10 @@
       }
       finally
       {
  -      if (-1 != m_varStackPos)
  +      if (-1 != m_stackFrame)
         {
           // These two statements need to be combined into one operation.
  -        vars.setSearchStart(savedStart);
  -        vars.popContextPosition();
  +        vars.setStackFrame(savedStart);
         }
       }
   
  
  
  
  1.1.2.4   +39 -41    xml-xalan/java/src/org/apache/xpath/axes/Attic/OneStepIteratorForward.java
  
  Index: OneStepIteratorForward.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/Attic/OneStepIteratorForward.java,v
  retrieving revision 1.1.2.3
  retrieving revision 1.1.2.4
  diff -u -r1.1.2.3 -r1.1.2.4
  --- OneStepIteratorForward.java	2001/06/03 03:09:23	1.1.2.3
  +++ OneStepIteratorForward.java	2001/06/11 20:16:46	1.1.2.4
  @@ -26,9 +26,6 @@
     /** The traversal axis from where the nodes will be filtered. */
     protected int m_axis = -1;
   
  -  /** The DTM inner traversal class, that corresponds to the super axis. */
  -  protected DTMAxisTraverser m_traverser;
  -
     /**
      * Create a OneStepIterator object.
      *
  @@ -63,44 +60,45 @@
       m_traverser = m_cdtm.getAxisTraverser(m_axis);
     }
     
  -  /**
  -   * Return the first node out of the nodeset, if this expression is 
  -   * a nodeset expression.  This is the default implementation for 
  -   * nodesets.
  -   * <p>WARNING: Do not mutate this class from this function!</p>
  -   * @param xctxt The XPath runtime context.
  -   * @return the first node out of the nodeset, or DTM.NULL.
  -   */
  -  public int asNode(XPathContext xctxt)
  -    throws javax.xml.transform.TransformerException
  -  {
  -    if(getPredicateCount() > 0)
  -      return super.asNode(xctxt);
  -      
  -    int current = xctxt.getCurrentNode();
  -    
  -    DTM dtm = xctxt.getDTM(current);
  -    DTMAxisTraverser traverser = dtm.getAxisTraverser(m_axis);
  -    
  -    String localName = getLocalName();
  -    String namespace = getNamespace();
  -    int what = m_whatToShow;
  -    
  -    // System.out.println("what: ");
  -    // NodeTest.debugWhatToShow(what);
  -    if(DTMFilter.SHOW_ALL == what
  -       || localName == NodeTest.WILD
  -       || namespace == NodeTest.WILD)
  -    {
  -      return traverser.first(current);
  -    }
  -    else
  -    {
  -      int type = getNodeTypeTest(what);
  -      int extendedType = dtm.getExpandedTypeID(namespace, localName, type);
  -      return traverser.first(current, extendedType);
  -    }
  -  }
  +//  /**
  +//   * Return the first node out of the nodeset, if this expression is 
  +//   * a nodeset expression.  This is the default implementation for 
  +//   * nodesets.
  +//   * <p>WARNING: Do not mutate this class from this function!</p>
  +//   * @param xctxt The XPath runtime context.
  +//   * @return the first node out of the nodeset, or DTM.NULL.
  +//   */
  +//  public int asNode(XPathContext xctxt)
  +//    throws javax.xml.transform.TransformerException
  +//  {
  +//    if(getPredicateCount() > 0)
  +//      return super.asNode(xctxt);
  +//      
  +//    int current = xctxt.getCurrentNode();
  +//    
  +//    DTM dtm = xctxt.getDTM(current);
  +//    DTMAxisTraverser traverser = dtm.getAxisTraverser(m_axis);
  +//    
  +//    String localName = getLocalName();
  +//    String namespace = getNamespace();
  +//    int what = m_whatToShow;
  +//    
  +//    // System.out.println("what: ");
  +//    // NodeTest.debugWhatToShow(what);
  +//    if(DTMFilter.SHOW_ALL == what
  +//       || ((DTMFilter.SHOW_ELEMENT & what) == 0)
  +//       || localName == NodeTest.WILD
  +//       || namespace == NodeTest.WILD)
  +//    {
  +//      return traverser.first(current);
  +//    }
  +//    else
  +//    {
  +//      int type = getNodeTypeTest(what);
  +//      int extendedType = dtm.getExpandedTypeID(namespace, localName, type);
  +//      return traverser.first(current, extendedType);
  +//    }
  +//  }
     
     /**
      * Get the next node via getFirstAttribute && getNextAttribute.
  
  
  
  1.3.2.7   +23 -0     xml-xalan/java/src/org/apache/xpath/axes/PredicatedNodeTest.java
  
  Index: PredicatedNodeTest.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/PredicatedNodeTest.java,v
  retrieving revision 1.3.2.6
  retrieving revision 1.3.2.7
  diff -u -r1.3.2.6 -r1.3.2.7
  --- PredicatedNodeTest.java	2001/06/04 07:52:58	1.3.2.6
  +++ PredicatedNodeTest.java	2001/06/11 20:16:47	1.3.2.7
  @@ -333,6 +333,29 @@
     }
     
     /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    super.fixupVariables(vars, globalsSize);
  +
  +    int nPredicates = getPredicateCount();
  +
  +    for (int i = 0; i < nPredicates; i++)
  +    {
  +      m_predicates[i].fixupVariables(vars, globalsSize);
  +    }
  +  }
  +
  +  
  +  /**
      * Diagnostics.
      *
      * @param n Node to give diagnostic information about, or null.
  
  
  
  1.15.2.10 +94 -13    xml-xalan/java/src/org/apache/xpath/axes/UnionPathIterator.java
  
  Index: UnionPathIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/UnionPathIterator.java,v
  retrieving revision 1.15.2.9
  retrieving revision 1.15.2.10
  diff -u -r1.15.2.9 -r1.15.2.10
  --- UnionPathIterator.java	2001/06/04 21:25:51	1.15.2.9
  +++ UnionPathIterator.java	2001/06/11 20:16:47	1.15.2.10
  @@ -116,17 +116,29 @@
       this.m_execContext = (XPathContext)environment;
       this.m_currentContextNode = context;
       this.m_context = context;
  +    m_lastFetched = DTM.NULL;
  +    m_next = 0;
  +    m_last = 0;
  +    m_foundLast = false;
   
  -    if (null != m_iterators)
  +    try
       {
  -      int n = m_iterators.length;
  -
  -      for (int i = 0; i < n; i++)
  +      if (null != m_iterators)
         {
  -        m_iterators[i].setRoot(context, environment);
  -        m_iterators[i].nextNode();
  +        int n = m_iterators.length;
  +  
  +        for (int i = 0; i < n; i++)
  +        {
  +          m_iterators[i] = ((LocPathIterator)m_iterators[i]).asIterator(m_execContext, context);
  +          m_iterators[i].setRoot(context, environment);
  +          m_iterators[i].nextNode();
  +        }
         }
       }
  +    catch(Exception e)
  +    {
  +      throw new org.apache.xml.utils.WrappedRuntimeException(e);
  +    }
     }
     
     /** Control over whether it is OK for detach to reset the iterator. */
  @@ -155,8 +167,21 @@
   
       if(m_allowDetach)
       {
  -      this.m_execContext = null;
  -      this.m_context = DTM.NULL;
  +      m_cachedNodes = null;
  +      m_execContext = null;
  +      // m_prefixResolver = null;
  +      // m_cdtm = null;
  +      
  +      if (null != m_iterators)
  +      {
  +        int n = m_iterators.length;
  +  
  +        for (int i = 0; i < n; i++)
  +        {
  +          m_iterators[i].detach();
  +        }
  +      }
  +
     
     //    int n = m_iterators.length;
     //
  @@ -430,11 +455,37 @@
   
       for (int i = 0; i < n; i++)
       {
  -      clone.m_iterators[i] = (LocPathIterator) m_iterators[i].clone();
  +      clone.m_iterators[i] = m_iterators[i];
       }
   
       return clone;
     }
  +  
  +  /**
  +   * <meta name="usage" content="experimental"/>
  +   * Given an select expression and a context, evaluate the XPath
  +   * and return the resulting iterator.
  +   * 
  +   * @param xctxt The execution context.
  +   * @param contextNode The node that "." expresses.
  +   * @param namespaceContext The context in which namespaces in the
  +   * XPath are supposed to be expanded.
  +   * 
  +   * @throws TransformerException thrown if the active ProblemListener decides
  +   * the error condition is severe enough to halt processing.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public DTMIterator asIterator(
  +          XPathContext xctxt, int contextNode)
  +            throws javax.xml.transform.TransformerException
  +  {
  +    UnionPathIterator clone = (UnionPathIterator)m_clones.getInstance();
  +    
  +    clone.setRoot(contextNode, xctxt);
  +    
  +    return clone;
  +  }
   
     /**
      * Reset the iterator.
  @@ -638,15 +689,22 @@
     public void runTo(int index)
     {
   
  -    if (m_foundLast || ((index >= 0) && (index <= m_next)))
  +    if (m_foundLast || ((index >= 0) && (index <= getCurrentPos())))
         return;
   
       int n;
   
  -    while (DTM.NULL == (n = nextNode()))
  +    if (-1 == index)
       {
  -      if (m_next >= index)
  -        break;
  +      while (DTM.NULL != (n = nextNode()));
  +    }
  +    else
  +    {
  +      while (DTM.NULL != (n = nextNode()))
  +      {
  +        if (getCurrentPos() >= index)
  +          break;
  +      }
       }
     }
   
  @@ -761,6 +819,29 @@
     public int getCurrentNode()
     {
       return m_lastFetched;
  +  }
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    for (int i = 0; i < m_iterators.length; i++) 
  +    {
  +      DTMIterator iter = m_iterators[i];
  +      if(iter instanceof Expression)
  +      {
  +        ((Expression)iter).fixupVariables(vars, globalsSize);
  +      }
  +    }
  +    
     }
   
     /**
  
  
  
  1.1.2.5   +27 -6     xml-xalan/java/src/org/apache/xpath/axes/Attic/WalkingIterator.java
  
  Index: WalkingIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/Attic/WalkingIterator.java,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- WalkingIterator.java	2001/06/04 13:51:40	1.1.2.4
  +++ WalkingIterator.java	2001/06/11 20:16:47	1.1.2.5
  @@ -150,7 +150,7 @@
       // may be much later than top-level iterators.  
       // m_varStackPos is set in setRoot, which is called 
       // from the execute method.
  -    if (-1 == m_varStackPos)
  +    if (-1 == m_stackFrame)
       {
         if (DTM.NULL == m_firstWalker.getRoot())
         {
  @@ -167,10 +167,9 @@
         VariableStack vars = m_execContext.getVarStack();
   
         // These three statements need to be combined into one operation.
  -      int savedStart = vars.getSearchStart();
  +      int savedStart = vars.getStackFrame();
   
  -      vars.setSearchStart(m_varStackPos);
  -      vars.pushContextPosition(m_varStackContext);
  +      vars.setStackFrame(m_stackFrame);
   
         if (DTM.NULL == m_firstWalker.getRoot())
         {
  @@ -183,8 +182,7 @@
         int n = returnNextNode(m_firstWalker.nextNode());
   
         // These two statements need to be combined into one operation.
  -      vars.setSearchStart(savedStart);
  -      vars.popContextPosition();
  +      vars.setStackFrame(savedStart);
   
         return n;
       }
  @@ -237,6 +235,29 @@
       
       // Always call the superclass detach last!
       super.detach();
  +  }
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    m_predicateIndex = 0;
  +
  +    AxesWalker walker = m_firstWalker;
  +
  +    while (null != walker)
  +    {
  +      walker.fixupVariables(vars, globalsSize);
  +      walker = walker.getNextWalker();
  +    }
     }
   
     
  
  
  
  1.1.2.4   +0 -2      xml-xalan/java/src/org/apache/xpath/axes/Attic/WalkingIteratorSorted.java
  
  Index: WalkingIteratorSorted.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/Attic/WalkingIteratorSorted.java,v
  retrieving revision 1.1.2.3
  retrieving revision 1.1.2.4
  diff -u -r1.1.2.3 -r1.1.2.4
  --- WalkingIteratorSorted.java	2001/06/04 07:41:04	1.1.2.3
  +++ WalkingIteratorSorted.java	2001/06/11 20:16:48	1.1.2.4
  @@ -158,7 +158,5 @@
       }
   
     }
  -
  -
     
   }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.5.2.7   +9 -0      xml-xalan/java/src/org/apache/xpath/functions/FuncCurrent.java
  
  Index: FuncCurrent.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/functions/FuncCurrent.java,v
  retrieving revision 1.5.2.6
  retrieving revision 1.5.2.7
  diff -u -r1.5.2.6 -r1.5.2.7
  --- FuncCurrent.java	2001/05/27 03:36:30	1.5.2.6
  +++ FuncCurrent.java	2001/06/11 20:16:52	1.5.2.7
  @@ -122,4 +122,13 @@
   
       return new XNodeSet(currentNode, xctxt.getDTMManager());
     }
  +  
  +  /**
  +   * No arguments to process, so this does nothing.
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    // no-op
  +  }
  +
   }
  
  
  
  1.7.2.4   +25 -0     xml-xalan/java/src/org/apache/xpath/functions/FuncExtFunction.java
  
  Index: FuncExtFunction.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/functions/FuncExtFunction.java,v
  retrieving revision 1.7.2.3
  retrieving revision 1.7.2.4
  diff -u -r1.7.2.3 -r1.7.2.4
  --- FuncExtFunction.java	2001/05/27 03:05:16	1.7.2.3
  +++ FuncExtFunction.java	2001/06/11 20:16:52	1.7.2.4
  @@ -96,6 +96,31 @@
      *  function.
      *  @serial   */
     Vector m_argVec = new Vector();
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    if(null != m_argVec)
  +    {
  +      int nArgs = m_argVec.size();
  +  
  +      for (int i = 0; i < nArgs; i++)
  +      {
  +        Expression arg = (Expression) m_argVec.elementAt(i);
  +        arg.fixupVariables(vars, globalsSize);
  +      }
  +    }
  +  }
  +
   
     /**
      * Create a new FuncExtFunction based on the qualified name of the extension, 
  
  
  
  1.3.2.2   +9 -0      xml-xalan/java/src/org/apache/xpath/functions/FuncFalse.java
  
  Index: FuncFalse.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/functions/FuncFalse.java,v
  retrieving revision 1.3.2.1
  retrieving revision 1.3.2.2
  diff -u -r1.3.2.1 -r1.3.2.2
  --- FuncFalse.java	2001/04/10 18:45:29	1.3.2.1
  +++ FuncFalse.java	2001/06/11 20:16:52	1.3.2.2
  @@ -84,4 +84,13 @@
     {
       return XBoolean.S_FALSE;
     }
  +  
  +  /**
  +   * No arguments to process, so this does nothing.
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    // no-op
  +  }
  +
   }
  
  
  
  1.6.2.4   +9 -0      xml-xalan/java/src/org/apache/xpath/functions/FuncLast.java
  
  Index: FuncLast.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/functions/FuncLast.java,v
  retrieving revision 1.6.2.3
  retrieving revision 1.6.2.4
  diff -u -r1.6.2.3 -r1.6.2.4
  --- FuncLast.java	2001/05/10 20:49:08	1.6.2.3
  +++ FuncLast.java	2001/06/11 20:16:53	1.6.2.4
  @@ -119,4 +119,13 @@
       // System.out.println("last: "+xnum.num());
       return xnum;
     }
  +  
  +  /**
  +   * No arguments to process, so this does nothing.
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    // no-op
  +  }
  +
   }
  
  
  
  1.4.2.3   +8 -0      xml-xalan/java/src/org/apache/xpath/functions/FuncPosition.java
  
  Index: FuncPosition.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/functions/FuncPosition.java,v
  retrieving revision 1.4.2.2
  retrieving revision 1.4.2.3
  diff -u -r1.4.2.2 -r1.4.2.3
  --- FuncPosition.java	2001/05/10 20:49:09	1.4.2.2
  +++ FuncPosition.java	2001/06/11 20:16:53	1.4.2.3
  @@ -155,4 +155,12 @@
       
       return new XNumber(pos);
     }
  +  
  +  /**
  +   * No arguments to process, so this does nothing.
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    // no-op
  +  }
   }
  
  
  
  1.5.2.2   +5 -4      xml-xalan/java/src/org/apache/xpath/functions/FuncSubstring.java
  
  Index: FuncSubstring.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/functions/FuncSubstring.java,v
  retrieving revision 1.5.2.1
  retrieving revision 1.5.2.2
  diff -u -r1.5.2.1 -r1.5.2.2
  --- FuncSubstring.java	2001/04/10 18:45:32	1.5.2.1
  +++ FuncSubstring.java	2001/06/11 20:16:53	1.5.2.2
  @@ -64,6 +64,7 @@
   import org.apache.xpath.XPath;
   import org.apache.xpath.objects.XObject;
   import org.apache.xpath.objects.XString;
  +import org.apache.xml.utils.XMLString;
   
   /**
    * <meta name="usage" content="advanced"/>
  @@ -83,10 +84,10 @@
     public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
     {
   
  -    String s1 = m_arg0.execute(xctxt).str();
  +    XMLString s1 = m_arg0.execute(xctxt).xstr();
       double start = m_arg1.execute(xctxt).num();
       int lenOfS1 = s1.length();
  -    String substr;
  +    XMLString substr;
   
       if (lenOfS1 <= 0)
         return XString.EMPTYSTRING;
  @@ -110,7 +111,7 @@
   
         if (null != m_arg2)
         {
  -        double len = m_arg2.execute(xctxt).num();
  +        double len = m_arg2.num(xctxt);
           int end = (int) (Math.round(len) + start) - 1;
   
           // Normalize end index.
  @@ -132,7 +133,7 @@
         }
       }
   
  -    return new XString(substr);
  +    return (XString)substr; // cast semi-safe
     }
   
     /**
  
  
  
  1.3.2.2   +9 -0      xml-xalan/java/src/org/apache/xpath/functions/FuncTrue.java
  
  Index: FuncTrue.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/functions/FuncTrue.java,v
  retrieving revision 1.3.2.1
  retrieving revision 1.3.2.2
  diff -u -r1.3.2.1 -r1.3.2.2
  --- FuncTrue.java	2001/04/10 18:45:34	1.3.2.1
  +++ FuncTrue.java	2001/06/11 20:16:54	1.3.2.2
  @@ -84,4 +84,13 @@
     {
       return XBoolean.S_TRUE;
     }
  +  
  +  /**
  +   * No arguments to process, so this does nothing.
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    // no-op
  +  }
  +
   }
  
  
  
  1.4.2.2   +3 -1      xml-xalan/java/src/org/apache/xpath/functions/Function.java
  
  Index: Function.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/functions/Function.java,v
  retrieving revision 1.4.2.1
  retrieving revision 1.4.2.2
  diff -u -r1.4.2.1 -r1.4.2.2
  --- Function.java	2001/04/10 18:45:34	1.4.2.1
  +++ Function.java	2001/06/11 20:16:54	1.4.2.2
  @@ -75,7 +75,7 @@
    * the arguments don't have to be added to an array, but causes
    * a larger code footprint.
    */
  -public class Function extends Expression
  +public abstract class Function extends Expression
   {
   
     /**
  @@ -126,4 +126,6 @@
   
       return null;
     }
  +  
  +
   }
  
  
  
  1.5.2.1   +18 -0     xml-xalan/java/src/org/apache/xpath/functions/Function2Args.java
  
  Index: Function2Args.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/functions/Function2Args.java,v
  retrieving revision 1.5
  retrieving revision 1.5.2.1
  diff -u -r1.5 -r1.5.2.1
  --- Function2Args.java	2001/01/02 03:47:16	1.5
  +++ Function2Args.java	2001/06/11 20:16:54	1.5.2.1
  @@ -79,6 +79,24 @@
     {
       return m_arg1;
     }
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    super.fixupVariables(vars, globalsSize);
  +    if(null != m_arg1)
  +      m_arg1.fixupVariables(vars, globalsSize);
  +  }
  +
   
     /**
      * Set an argument expression for a function.  This method is called by the 
  
  
  
  1.6.2.1   +17 -0     xml-xalan/java/src/org/apache/xpath/functions/Function3Args.java
  
  Index: Function3Args.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/functions/Function3Args.java,v
  retrieving revision 1.6
  retrieving revision 1.6.2.1
  diff -u -r1.6 -r1.6.2.1
  --- Function3Args.java	2001/01/02 03:47:16	1.6
  +++ Function3Args.java	2001/06/11 20:16:55	1.6.2.1
  @@ -79,6 +79,23 @@
     {
       return m_arg2;
     }
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    super.fixupVariables(vars, globalsSize);
  +    if(null != m_arg2)
  +      m_arg2.fixupVariables(vars, globalsSize);
  +  }
   
     /**
      * Set an argument expression for a function.  This method is called by the 
  
  
  
  1.6.2.1   +22 -0     xml-xalan/java/src/org/apache/xpath/functions/FunctionMultiArgs.java
  
  Index: FunctionMultiArgs.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/functions/FunctionMultiArgs.java,v
  retrieving revision 1.6
  retrieving revision 1.6.2.1
  diff -u -r1.6 -r1.6.2.1
  --- FunctionMultiArgs.java	2001/01/02 03:47:16	1.6
  +++ FunctionMultiArgs.java	2001/06/11 20:16:55	1.6.2.1
  @@ -106,6 +106,28 @@
         }
       }
     }
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    super.fixupVariables(vars, globalsSize);
  +    if(null != m_args)
  +    {
  +      for (int i = 0; i < m_args.length; i++) 
  +      {
  +        m_args[i].fixupVariables(vars, globalsSize);
  +      }
  +    }
  +  }
   
     /**
      * Check that the number of arguments passed to this function is correct.
  
  
  
  1.5.2.2   +16 -0     xml-xalan/java/src/org/apache/xpath/functions/FunctionOneArg.java
  
  Index: FunctionOneArg.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/functions/FunctionOneArg.java,v
  retrieving revision 1.5.2.1
  retrieving revision 1.5.2.2
  diff -u -r1.5.2.1 -r1.5.2.2
  --- FunctionOneArg.java	2001/05/29 14:31:48	1.5.2.1
  +++ FunctionOneArg.java	2001/06/11 20:16:55	1.5.2.2
  @@ -123,5 +123,21 @@
      {
       return m_arg0.canTraverseOutsideSubtree();
      }
  +   
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    if(null != m_arg0)
  +      m_arg0.fixupVariables(vars, globalsSize);
  +  }
   
   }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.10.2.7  +18 -7     xml-xalan/java/src/org/apache/xpath/objects/XNodeSet.java
  
  Index: XNodeSet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/objects/XNodeSet.java,v
  retrieving revision 1.10.2.6
  retrieving revision 1.10.2.7
  diff -u -r1.10.2.6 -r1.10.2.7
  --- XNodeSet.java	2001/06/04 21:25:53	1.10.2.6
  +++ XNodeSet.java	2001/06/11 20:16:59	1.10.2.7
  @@ -154,7 +154,8 @@
      */
     public double getNumberFromNode(int n)
     {
  -    return m_dtmMgr.getDTM(n).getStringValue(n).toDouble();
  +    XMLString xstr = m_dtmMgr.getDTM(n).getStringValue(n);
  +    return xstr.toDouble();
     }
   
     /**
  @@ -235,7 +236,8 @@
      */
     public void allowDetachToRelease(boolean allowRelease)
     {
  -    ((DTMIterator) m_obj).allowDetachToRelease(allowRelease);
  +    if(null != m_obj)
  +      ((DTMIterator) m_obj).allowDetachToRelease(allowRelease);
     }
   
     /**
  @@ -247,7 +249,12 @@
      */
     public void detach()
     {
  -    ((DTMIterator) m_obj).detach();
  +    if(null != m_obj)
  +    {
  +      Object obj = m_obj;
  +      m_obj = null;
  +      ((DTMIterator) obj).detach();
  +    }
     }
   
   
  @@ -668,7 +675,8 @@
      */
     boolean compareStrings(XMLString s1, XMLString s2)
     {
  -    return s1.compareTo(s2) < 0;
  +    return (s1.toDouble() < s2.toDouble());
  +    // return s1.compareTo(s2) < 0;
     }
   
     /**
  @@ -703,7 +711,8 @@
      */
     boolean compareStrings(XMLString s1, XMLString s2)
     {
  -    return s1.compareTo(s2) <= 0;
  +    return (s1.toDouble() <= s2.toDouble());
  +    // return s1.compareTo(s2) <= 0;
     }
   
     /**
  @@ -738,7 +747,8 @@
      */
     boolean compareStrings(XMLString s1, XMLString s2)
     {
  -    return s1.compareTo(s2) > 0;
  +    return (s1.toDouble() > s2.toDouble());
  +    // return s1.compareTo(s2) > 0;
     }
   
     /**
  @@ -773,7 +783,8 @@
      */
     boolean compareStrings(XMLString s1, XMLString s2)
     {
  -    return s1.compareTo(s2) >= 0;
  +    return (s1.toDouble() >= s2.toDouble());
  +    // return s1.compareTo(s2) >= 0;
     }
   
     /**
  
  
  
  1.8.2.4   +187 -172  xml-xalan/java/src/org/apache/xpath/objects/XNumber.java
  
  Index: XNumber.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/objects/XNumber.java,v
  retrieving revision 1.8.2.3
  retrieving revision 1.8.2.4
  diff -u -r1.8.2.3 -r1.8.2.4
  --- XNumber.java	2001/05/18 07:17:20	1.8.2.3
  +++ XNumber.java	2001/06/11 20:17:00	1.8.2.4
  @@ -58,6 +58,7 @@
   
   import org.w3c.dom.*;
   import java.math.BigDecimal;
  +import org.apache.xpath.XPathContext;
   
   /**
    * <meta name="usage" content="general"/>
  @@ -114,7 +115,21 @@
     {
       return m_val;
     }
  +  
  +  /**
  +   * Evaluate expression to a number.
  +   *
  +   * @return 0.0
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public double num(XPathContext xctxt) 
  +    throws javax.xml.transform.TransformerException
  +  {
   
  +    return m_val;
  +  }
  +
     /**
      * Cast result object to a boolean.
      *
  @@ -125,162 +140,13 @@
       return (Double.isNaN(m_val) || (m_val == 0.0)) ? false : true;
     }
   
  -//  /**
  -//   * Cast result object to a string.
  -//   *
  -//   * @return "NaN" if the number is NaN, Infinity or -Infinity if
  -//   * the number is infinite or the string value of the number.
  -//   */
  -//  private static final int PRECISION = 16;
  -//  public String str()
  -//  {
  -//
  -//    if (Double.isNaN(m_val))
  -//    {
  -//      return "NaN";
  -//    }
  -//    else if (Double.isInfinite(m_val))
  -//    {
  -//      if (m_val > 0)
  -//        return "Infinity";
  -//      else
  -//        return "-Infinity";
  -//    }
  -//
  -//    long longVal = (long)m_val;
  -//    if ((double)longVal == m_val)
  -//      return Long.toString(longVal);
  -//
  -//
  -//    String s = Double.toString(m_val);
  -//    int len = s.length();
  -//
  -//    if (s.charAt(len - 2) == '.' && s.charAt(len - 1) == '0')
  -//    {
  -//      return s.substring(0, len - 2);
  -//    }
  -//
  -//    int exp = 0;
  -//    int e = s.indexOf('E');
  -//    if (e != -1)
  -//    {
  -//      exp = Integer.parseInt(s.substring(e + 1));
  -//      s = s.substring(0,e);
  -//      len = e;
  -//    }
  -//
  -//    // Calculate Significant Digits:
  -//    // look from start of string for first digit
  -//    // look from end for last digit
  -//    // significant digits = end - start + (0 or 1 depending on decimal location)
  -//
  -//    int decimalPos = -1;
  -//    int start = (s.charAt(0) == '-') ? 1 : 0;
  -//    findStart: for( ; start < len; start++ )
  -//    {
  -//      switch (s.charAt(start))
  -//      {
  -//      case '0':
  -//        break;
  -//      case '.':
  -//        decimalPos = start;
  -//        break;
  -//      default:
  -//        break findStart;
  -//      }
  -//    }
  -//    int end = s.length() - 1;
  -//    findEnd: for( ; end > start; end-- )
  -//    {
  -//      switch (s.charAt(end))
  -//      {
  -//      case '0':
  -//        break;
  -//      case '.':
  -//        decimalPos = end;
  -//        break;
  -//      default:
  -//        break findEnd;
  -//      }
  -//    }
  -//
  -//    int sigDig = end - start;
  -//
  -//    // clarify decimal location if it has not yet been found
  -//    if (decimalPos == -1)
  -//      decimalPos = s.indexOf('.');
  -//
  -//    // if decimal is not between start and end, add one to sigDig
  -//    if (decimalPos < start || decimalPos > end)
  -//      ++sigDig;
  -//
  -//    // reduce significant digits to PRECISION if necessary
  -//    if (sigDig > PRECISION)
  -//    {
  -//      // re-scale BigDecimal in order to get significant digits = PRECISION
  -//      BigDecimal num = new BigDecimal(s);
  -//      int newScale = num.scale() - (sigDig - PRECISION);
  -//      if (newScale < 0)
  -//        newScale = 0;
  -//      s = num.setScale(newScale, BigDecimal.ROUND_HALF_UP).toString();
  -//
  -//      // remove trailing '0's; keep track of decimalPos
  -//      int truncatePoint = s.length();
  -//      while (s.charAt(--truncatePoint) == '0')
  -//        ;
  -//
  -//      if (s.charAt(truncatePoint) == '.')
  -//      {
  -//        decimalPos = truncatePoint;
  -//      }
  -//      else
  -//      {
  -//        decimalPos = s.indexOf('.');
  -//        truncatePoint += 1;
  -//      }
  -//
  -//      s = s.substring(0, truncatePoint);
  -//      len = s.length();
  -//    }
  -//
  -//    // Account for exponent by adding zeros as needed 
  -//    // and moving the decimal place
  -//
  -//    if (exp == 0)
  -//       return s;
  -//
  -//    start = 0;
  -//    String sign;
  -//    if (s.charAt(0) == '-')
  -//    {
  -//      sign = "-";
  -//      start++;
  -//    }
  -//    else
  -//      sign = "";
  -//
  -//    String wholePart = s.substring(start, decimalPos);
  -//    String decimalPart = s.substring(decimalPos + 1);
  -//
  -//    // get the number of digits right of the decimal
  -//    int decimalLen = decimalPart.length();
  -//
  -//    if (exp >= decimalLen)
  -//      return sign + wholePart + decimalPart + zeros(exp - decimalLen);
  -//
  -//    if (exp > 0)
  -//      return sign + wholePart + decimalPart.substring(0, exp) + "."
  -//             + decimalPart.substring(exp);
  -//
  -//    return sign + "0." + zeros(-1 - exp) + wholePart + decimalPart;
  -//  }
  -
     /**
      * Cast result object to a string.
      *
      * @return "NaN" if the number is NaN, Infinity or -Infinity if
      * the number is infinite or the string value of the number.
      */
  +  private static final int PRECISION = 16;
     public String str()
     {
   
  @@ -295,52 +161,201 @@
         else
           return "-Infinity";
       }
  +
  +    long longVal = (long)m_val;
  +    if ((double)longVal == m_val)
  +      return Long.toString(longVal);
  +
   
  -    double num = m_val;
  -    String s = Double.toString(num);
  +    String s = Double.toString(m_val);
       int len = s.length();
   
       if (s.charAt(len - 2) == '.' && s.charAt(len - 1) == '0')
       {
  -      s = s.substring(0, len - 2);
  +      return s.substring(0, len - 2);
  +    }
   
  -      if (s.equals("-0"))
  -        return "0";
  +    int exp = 0;
  +    int e = s.indexOf('E');
  +    if (e != -1)
  +    {
  +      exp = Integer.parseInt(s.substring(e + 1));
  +      s = s.substring(0,e);
  +      len = e;
  +    }
   
  -      return s;
  +    // Calculate Significant Digits:
  +    // look from start of string for first digit
  +    // look from end for last digit
  +    // significant digits = end - start + (0 or 1 depending on decimal location)
  +
  +    int decimalPos = -1;
  +    int start = (s.charAt(0) == '-') ? 1 : 0;
  +    findStart: for( ; start < len; start++ )
  +    {
  +      switch (s.charAt(start))
  +      {
  +      case '0':
  +        break;
  +      case '.':
  +        decimalPos = start;
  +        break;
  +      default:
  +        break findStart;
  +      }
  +    }
  +    int end = s.length() - 1;
  +    findEnd: for( ; end > start; end-- )
  +    {
  +      switch (s.charAt(end))
  +      {
  +      case '0':
  +        break;
  +      case '.':
  +        decimalPos = end;
  +        break;
  +      default:
  +        break findEnd;
  +      }
       }
   
  -    int e = s.indexOf('E');
  +    int sigDig = end - start;
   
  -    if (e < 0)
  -      return s;
  +    // clarify decimal location if it has not yet been found
  +    if (decimalPos == -1)
  +      decimalPos = s.indexOf('.');
  +
  +    // if decimal is not between start and end, add one to sigDig
  +    if (decimalPos < start || decimalPos > end)
  +      ++sigDig;
   
  -    int exp = Integer.parseInt(s.substring(e + 1));
  -    String sign;
  +    // reduce significant digits to PRECISION if necessary
  +    if (sigDig > PRECISION)
  +    {
  +      // re-scale BigDecimal in order to get significant digits = PRECISION
  +      BigDecimal num = new BigDecimal(s);
  +      int newScale = num.scale() - (sigDig - PRECISION);
  +      if (newScale < 0)
  +        newScale = 0;
  +      s = num.setScale(newScale, BigDecimal.ROUND_HALF_UP).toString();
  +
  +      // remove trailing '0's; keep track of decimalPos
  +      int truncatePoint = s.length();
  +      while (s.charAt(--truncatePoint) == '0')
  +        ;
  +
  +      if (s.charAt(truncatePoint) == '.')
  +      {
  +        decimalPos = truncatePoint;
  +      }
  +      else
  +      {
  +        decimalPos = s.indexOf('.');
  +        truncatePoint += 1;
  +      }
  +
  +      s = s.substring(0, truncatePoint);
  +      len = s.length();
  +    }
  +
  +    // Account for exponent by adding zeros as needed 
  +    // and moving the decimal place
  +
  +    if (exp == 0)
  +       return s;
   
  +    start = 0;
  +    String sign;
       if (s.charAt(0) == '-')
       {
         sign = "-";
  -      s = s.substring(1);
  -
  -      --e;
  +      start++;
       }
       else
         sign = "";
  +
  +    String wholePart = s.substring(start, decimalPos);
  +    String decimalPart = s.substring(decimalPos + 1);
   
  -    int nDigits = e - 2;
  +    // get the number of digits right of the decimal
  +    int decimalLen = decimalPart.length();
   
  -    if (exp >= nDigits)
  -      return sign + s.substring(0, 1) + s.substring(2, e)
  -             + zeros(exp - nDigits);
  +    if (exp >= decimalLen)
  +      return sign + wholePart + decimalPart + zeros(exp - decimalLen);
   
       if (exp > 0)
  -      return sign + s.substring(0, 1) + s.substring(2, 2 + exp) + "."
  -             + s.substring(2 + exp, e);
  +      return sign + wholePart + decimalPart.substring(0, exp) + "."
  +             + decimalPart.substring(exp);
   
  -    return sign + "0." + zeros(-1 - exp) + s.substring(0, 1)
  -           + s.substring(2, e);
  +    return sign + "0." + zeros(-1 - exp) + wholePart + decimalPart;
     }
  +
  +//  /**
  +//   * Cast result object to a string.
  +//   *
  +//   * @return "NaN" if the number is NaN, Infinity or -Infinity if
  +//   * the number is infinite or the string value of the number.
  +//   */
  +//  public String str()
  +//  {
  +//
  +//    if (Double.isNaN(m_val))
  +//    {
  +//      return "NaN";
  +//    }
  +//    else if (Double.isInfinite(m_val))
  +//    {
  +//      if (m_val > 0)
  +//        return "Infinity";
  +//      else
  +//        return "-Infinity";
  +//    }
  +//
  +//    double num = m_val;
  +//    String s = Double.toString(num);
  +//    int len = s.length();
  +//
  +//    if (s.charAt(len - 2) == '.' && s.charAt(len - 1) == '0')
  +//    {
  +//      s = s.substring(0, len - 2);
  +//
  +//      if (s.equals("-0"))
  +//        return "0";
  +//
  +//      return s;
  +//    }
  +//
  +//    int e = s.indexOf('E');
  +//
  +//    if (e < 0)
  +//      return s;
  +//
  +//    int exp = Integer.parseInt(s.substring(e + 1));
  +//    String sign;
  +//
  +//    if (s.charAt(0) == '-')
  +//    {
  +//      sign = "-";
  +//      s = s.substring(1);
  +//
  +//      --e;
  +//    }
  +//    else
  +//      sign = "";
  +//
  +//    int nDigits = e - 2;
  +//
  +//    if (exp >= nDigits)
  +//      return sign + s.substring(0, 1) + s.substring(2, e)
  +//             + zeros(exp - nDigits);
  +//
  +//    if (exp > 0)
  +//      return sign + s.substring(0, 1) + s.substring(2, 2 + exp) + "."
  +//             + s.substring(2 + exp, e);
  +//
  +//    return sign + "0." + zeros(-1 - exp) + s.substring(0, 1)
  +//           + s.substring(2, e);
  +//  }
   
   
     /**
  
  
  
  1.8.2.9   +96 -39    xml-xalan/java/src/org/apache/xpath/objects/XObject.java
  
  Index: XObject.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/objects/XObject.java,v
  retrieving revision 1.8.2.8
  retrieving revision 1.8.2.9
  diff -u -r1.8.2.8 -r1.8.2.9
  --- XObject.java	2001/05/29 14:31:54	1.8.2.8
  +++ XObject.java	2001/06/11 20:17:00	1.8.2.9
  @@ -60,7 +60,6 @@
   //import org.w3c.dom.Text;
   //import org.w3c.dom.Node;
   //import org.w3c.dom.traversal.NodeIterator;
  -
   import org.apache.xml.dtm.DTM;
   import org.apache.xml.dtm.DTMIterator;
   
  @@ -81,11 +80,13 @@
    * This class acts as the base class to other XPath type objects,
    * such as XString, and provides polymorphic casting capabilities.
    */
  -public class XObject extends Expression implements Serializable
  +public class XObject extends Expression implements Serializable, Cloneable
   {
   
  -  /** The java object which this object wraps.
  -   *  @serial  */
  +  /**
  +   * The java object which this object wraps.
  +   *  @serial  
  +   */
     protected Object m_obj;  // This may be NULL!!!
   
     /**
  @@ -96,7 +97,7 @@
     /**
      * Create an XObject.
      *
  -   * @param obj Can be any object, should be a specific type 
  +   * @param obj Can be any object, should be a specific type
      * for derived classes, or null.
      */
     public XObject(Object obj)
  @@ -113,11 +114,45 @@
      *
      * @throws javax.xml.transform.TransformerException
      */
  -  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
  +  public XObject execute(XPathContext xctxt)
  +          throws javax.xml.transform.TransformerException
     {
       return this;
     }
  -  
  +
  +  /**
  +   * Specify if it's OK for detach to release the iterator for reuse.
  +   *
  +   * @param allowRelease true if it is OK for detach to release this iterator
  +   * for pooling.
  +   */
  +  public void allowDetachToRelease(boolean allowRelease){}
  +
  +  /**
  +   * Detaches the <code>DTMIterator</code> from the set which it iterated
  +   * over, releasing any computational resources and placing the iterator
  +   * in the INVALID state. After <code>detach</code> has been invoked,
  +   * calls to <code>nextNode</code> or <code>previousNode</code> will
  +   * raise a runtime exception.
  +   */
  +  public void detach(){}
  +
  +  /**
  +   * Forces the object to release it's resources.  This is more harsh than
  +   * detach().
  +   */
  +  public void destruct()
  +  {
  +
  +    if (null != m_obj)
  +    {
  +      allowDetachToRelease(true);
  +      detach();
  +
  +      m_obj = null;
  +    }
  +  }
  +
     /**
      * Directly call the
      * characters method on the passed ContentHandler for the
  @@ -166,18 +201,21 @@
       }
       else if (val instanceof org.w3c.dom.DocumentFragment)
       {
  +
         // result = new XRTreeFrag((DocumentFragment) val);
         // %REVIEW%
         result = new XObject(val);
       }
       else if (val instanceof org.w3c.dom.traversal.NodeIterator)
       {
  +
         // result = new XNodeSet((NodeIterator) val);
         // %REVIEW%
         result = new XObject(val);
       }
       else if (val instanceof org.w3c.dom.Node)
       {
  +
         // result = new XNodeSet(xctxt.getDTMHandleFromNode((org.w3c.dom.Node)val), 
         //                      xctxt.getDTMManager());
         // %REVIEW%
  @@ -191,28 +229,28 @@
       return result;
     }
   
  -  /** Constant for NULL object type          */
  +  /** Constant for NULL object type */
     public static final int CLASS_NULL = -1;
   
  -  /** Constant for UNKNOWN object type         */
  +  /** Constant for UNKNOWN object type */
     public static final int CLASS_UNKNOWN = 0;
   
  -  /** Constant for BOOLEAN  object type        */
  +  /** Constant for BOOLEAN  object type */
     public static final int CLASS_BOOLEAN = 1;
   
  -  /** Constant for NUMBER object type         */
  +  /** Constant for NUMBER object type */
     public static final int CLASS_NUMBER = 2;
   
  -  /** Constant for STRING object type         */
  +  /** Constant for STRING object type */
     public static final int CLASS_STRING = 3;
   
  -  /** Constant for NODESET object type         */
  +  /** Constant for NODESET object type */
     public static final int CLASS_NODESET = 4;
   
  -  /** Constant for RESULT TREE FRAGMENT object type         */
  +  /** Constant for RESULT TREE FRAGMENT object type */
     public static final int CLASS_RTREEFRAG = 5;
   
  -  /** Represents an unresolved variable type as an integer.          */
  +  /** Represents an unresolved variable type as an integer. */
     public static final int CLASS_UNRESOLVEDVARIABLE = 600;
   
     /**
  @@ -267,7 +305,7 @@
   
       return false;
     }
  -  
  +
     /**
      * Cast result object to a string.
      *
  @@ -285,11 +323,11 @@
      */
     public String str()
     {
  -    return (m_obj != null) ? m_obj.toString() : "";    
  +    return (m_obj != null) ? m_obj.toString() : "";
     }
   
     /**
  -   * Return the string representation of the object 
  +   * Return the string representation of the object
      *
      *
      * @return the string representation of the object
  @@ -314,9 +352,10 @@
       if (DTM.NULL == result)
       {
         DTM frag = support.createDocumentFragment();
  -      
  +
         // %OPT%
         frag.appendTextChild(str());
  +
         result = frag.getDocument();
       }
   
  @@ -367,7 +406,8 @@
      *
      * @throws javax.xml.transform.TransformerException
      */
  -  public NodeSet mutableNodeset() throws javax.xml.transform.TransformerException
  +  public NodeSet mutableNodeset()
  +          throws javax.xml.transform.TransformerException
     {
   
       error(XPATHErrorResources.ER_CANT_CONVERT_TO_MUTABLENODELIST,
  @@ -380,7 +420,7 @@
      * Cast object to type t.
      *
      * @param t Type of object to cast this to
  -   * @param support XPath context to use for the conversion 
  +   * @param support XPath context to use for the conversion
      *
      * @return This object as the given type t
      *
  @@ -409,10 +449,11 @@
       case CLASS_UNKNOWN :
         result = m_obj;
         break;
  -      // %TBD%  What to do here?
  -//    case CLASS_RTREEFRAG :
  -//      result = rtree(support);
  -//      break;
  +
  +    // %TBD%  What to do here?
  +    //    case CLASS_RTREEFRAG :
  +    //      result = rtree(support);
  +    //      break;
       default :
         error(XPATHErrorResources.ER_CANT_CONVERT_TO_TYPE,
               new Object[]{ getTypeString(),
  @@ -429,11 +470,12 @@
      *
      * @param obj2 Object to compare this to
      *
  -   * @return True if this object is less than the given object 
  +   * @return True if this object is less than the given object
      *
      * @throws javax.xml.transform.TransformerException
      */
  -  public boolean lessThan(XObject obj2) throws javax.xml.transform.TransformerException
  +  public boolean lessThan(XObject obj2)
  +          throws javax.xml.transform.TransformerException
     {
   
       // In order to handle the 'all' semantics of 
  @@ -452,11 +494,12 @@
      *
      * @param obj2 Object to compare this to
      *
  -   * @return True if this object is less than or equal to the given object 
  +   * @return True if this object is less than or equal to the given object
      *
      * @throws javax.xml.transform.TransformerException
      */
  -  public boolean lessThanOrEqual(XObject obj2) throws javax.xml.transform.TransformerException
  +  public boolean lessThanOrEqual(XObject obj2)
  +          throws javax.xml.transform.TransformerException
     {
   
       // In order to handle the 'all' semantics of 
  @@ -475,11 +518,12 @@
      *
      * @param obj2 Object to compare this to
      *
  -   * @return True if this object is greater than the given object 
  +   * @return True if this object is greater than the given object
      *
      * @throws javax.xml.transform.TransformerException
      */
  -  public boolean greaterThan(XObject obj2) throws javax.xml.transform.TransformerException
  +  public boolean greaterThan(XObject obj2)
  +          throws javax.xml.transform.TransformerException
     {
   
       // In order to handle the 'all' semantics of 
  @@ -498,7 +542,7 @@
      *
      * @param obj2 Object to compare this to
      *
  -   * @return True if this object is greater than or equal to the given object 
  +   * @return True if this object is greater than or equal to the given object
      *
      * @throws javax.xml.transform.TransformerException
      */
  @@ -522,7 +566,7 @@
      *
      * @param obj2 Object to compare this to
      *
  -   * @return True if this object is equal to the given object 
  +   * @return True if this object is equal to the given object
      *
      * @throws javax.xml.transform.TransformerException
      */
  @@ -550,11 +594,12 @@
      *
      * @param obj2 Object to compare this to
      *
  -   * @return True if this object is not equal to the given object 
  +   * @return True if this object is not equal to the given object
      *
      * @throws javax.xml.transform.TransformerException
      */
  -  public boolean notEquals(XObject obj2) throws javax.xml.transform.TransformerException
  +  public boolean notEquals(XObject obj2)
  +          throws javax.xml.transform.TransformerException
     {
   
       // In order to handle the 'all' semantics of 
  @@ -574,7 +619,8 @@
      *
      * @throws javax.xml.transform.TransformerException
      */
  -  protected void error(int msg) throws javax.xml.transform.TransformerException
  +  protected void error(int msg)
  +          throws javax.xml.transform.TransformerException
     {
       error(msg, null);
     }
  @@ -584,11 +630,12 @@
      * exception.
      *
      * @param msg Error message to issue
  -   * @param args Arguments to use in the message 
  +   * @param args Arguments to use in the message
      *
      * @throws javax.xml.transform.TransformerException
      */
  -  protected void error(int msg, Object[] args) throws javax.xml.transform.TransformerException
  +  protected void error(int msg, Object[] args)
  +          throws javax.xml.transform.TransformerException
     {
   
       String fmsg = XSLMessages.createXPATHMessage(msg, args);
  @@ -604,13 +651,23 @@
     }
     
     /**
  +   * XObjects should not normally need to fix up variables.
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    // no-op
  +  }
  +
  +
  +  /**
      * Cast result object to a string.
      *
  +   *
  +   * NEEDSDOC @param fsb
      * @return The string this wraps or the empty string if null
      */
     public void appendToFsb(org.apache.xml.utils.FastStringBuffer fsb)
     {
       fsb.append(str());
     }
  -
   }
  
  
  
  1.13.2.5  +82 -7     xml-xalan/java/src/org/apache/xpath/objects/XRTreeFrag.java
  
  Index: XRTreeFrag.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/objects/XRTreeFrag.java,v
  retrieving revision 1.13.2.4
  retrieving revision 1.13.2.5
  diff -u -r1.13.2.4 -r1.13.2.5
  --- XRTreeFrag.java	2001/05/19 07:05:57	1.13.2.4
  +++ XRTreeFrag.java	2001/06/11 20:17:00	1.13.2.5
  @@ -56,9 +56,6 @@
    */
   package org.apache.xpath.objects;
   
  -//import org.w3c.dom.*;
  -//import org.w3c.dom.traversal.NodeIterator;
  -//import org.w3c.dom.traversal.NodeFilter;
   import org.apache.xml.dtm.DTM;
   import org.apache.xml.dtm.DTMIterator;
   import org.apache.xml.dtm.DTMFilter;
  @@ -67,17 +64,19 @@
   
   import org.apache.xpath.DOMHelper;
   import org.apache.xpath.XPathContext;
  +import org.apache.xpath.Expression;
   
   /**
    * <meta name="usage" content="general"/>
    * This class represents an XPath result tree fragment object, and is capable of
    * converting the RTF to other types, such as a string.
    */
  -public class XRTreeFrag extends XObject
  +public class XRTreeFrag extends XObject implements Cloneable
   {
     DTM m_dtm;
     int m_dtmRoot;
     XPathContext m_xctxt;
  +  boolean m_allowRelease = true;
   
   //  /**
   //   * Create an XRTreeFrag Object.
  @@ -106,8 +105,85 @@
       m_xctxt = xctxt;
       m_dtm = xctxt.getDTM(root);
     }
  +  
  +  /**
  +   * Create an XRTreeFrag Object.
  +   *
  +   * @param frag Document fragment this will wrap
  +   */
  +  public XRTreeFrag(Expression expr)
  +  {
  +    super(expr);
  +  }
  +  
  +  /**
  +   * Release any resources this object may have by calling destruct().
  +   *
  +   * @throws Throwable
  +   */
  +  protected void finalize() throws Throwable
  +  {
  +
  +    try
  +    {
  +      destruct();
  +    }
  +    finally
  +    {
  +      super.finalize();  // Always use this.
  +    }
  +  }
  +  
  +  /**
  +   * Specify if it's OK for detach to release the iterator for reuse.
  +   * 
  +   * @param allowRelease true if it is OK for detach to release this iterator 
  +   * for pooling.
  +   */
  +  public void allowDetachToRelease(boolean allowRelease)
  +  {
  +    m_allowRelease = allowRelease;
  +  }
   
     /**
  +   * Detaches the <code>DTMIterator</code> from the set which it iterated
  +   * over, releasing any computational resources and placing the iterator
  +   * in the INVALID state. After <code>detach</code> has been invoked,
  +   * calls to <code>nextNode</code> or <code>previousNode</code> will
  +   * raise a runtime exception.
  +   * 
  +   * In general, detach should only be called once on the object.
  +   */
  +  public void detach()
  +  {
  +    if(m_allowRelease)
  +    {
  +      if(null != m_dtm)
  +      {
  +        m_xctxt.release(m_dtm, true);
  +        m_dtm = null;
  +        m_xctxt = null;
  +      }
  +      m_obj = null;
  +    }
  +  }
  +  
  +  /**
  +   * Forces the object to release it's resources.  This is more harsh than 
  +   * detach().  You can call destruct as many times as you want.
  +   */
  +  public void destruct()
  +  {
  +    if(null != m_dtm)
  +    {
  +      m_xctxt.release(m_dtm, true);
  +      m_dtm = null;
  +      m_xctxt = null;
  +    }
  +    m_obj = null;
  + }
  +
  +  /**
      * Tell what kind of class this is.
      *
      * @return type CLASS_RTREEFRAG 
  @@ -134,11 +210,10 @@
      * @return The result tree fragment as a number or NaN
      */
     public double num()
  +    throws javax.xml.transform.TransformerException
     {
   
  -    double result;
  -    
  -    XMLString s = m_dtm.getStringValue(m_dtmRoot);
  +    XMLString s = xstr();
   
       return s.toDouble();
     }
  
  
  
  1.6.2.11  +3 -3      xml-xalan/java/src/org/apache/xpath/objects/XString.java
  
  Index: XString.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/objects/XString.java,v
  retrieving revision 1.6.2.10
  retrieving revision 1.6.2.11
  diff -u -r1.6.2.10 -r1.6.2.11
  --- XString.java	2001/06/04 07:53:00	1.6.2.10
  +++ XString.java	2001/06/11 20:17:01	1.6.2.11
  @@ -164,7 +164,7 @@
       {
         char c = charAt(i);
   
  -      if (!Character.isSpaceChar(c))
  +      if (!XMLCharacterRecognizer.isWhiteSpace(c))
         {
           break;
         }
  @@ -189,7 +189,7 @@
   
         if (c != '.')
         {
  -        if (Character.isSpaceChar(c))
  +        if (XMLCharacterRecognizer.isWhiteSpace(c))
             break;
           else if (Character.isDigit(c))
           {
  @@ -218,7 +218,7 @@
         {
           char c = charAt(i);
   
  -        if (Character.isSpaceChar(c))
  +        if (XMLCharacterRecognizer.isWhiteSpace(c))
             break;
           else if (Character.isDigit(c))
           {
  
  
  
  1.1.2.3   +4 -4      xml-xalan/java/src/org/apache/xpath/objects/Attic/XStringForFSB.java
  
  Index: XStringForFSB.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/objects/Attic/XStringForFSB.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- XStringForFSB.java	2001/05/19 07:05:59	1.1.2.2
  +++ XStringForFSB.java	2001/06/11 20:17:01	1.1.2.3
  @@ -970,7 +970,7 @@
       for (int i = start; i < end; i++) 
       {
         char c = fsb.charAt(i);
  -      if( !Character.isSpaceChar( c ) )
  +      if( !XMLCharacterRecognizer.isWhiteSpace( c ) )
         {
           break;
         }
  @@ -992,7 +992,7 @@
         char c = fsb.charAt(i);
         if (c != '.')
         {
  -        if(Character.isSpaceChar(c))
  +        if(XMLCharacterRecognizer.isWhiteSpace(c))
             break;
           else if (Character.isDigit(c))
           {
  @@ -1018,8 +1018,8 @@
         for (int i = end - 1; i > punctPos; i--)
         {
           char c = fsb.charAt(i);
  -        if(Character.isSpaceChar(c))
  -          break;
  +        if(XMLCharacterRecognizer.isWhiteSpace(c))
  +          continue;
           else if (Character.isDigit(c))
           {
             fractPart = fractPart / 10.0 + (c - 0x30);
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.1   +128 -0    xml-xalan/java/src/org/apache/xpath/objects/Attic/XRTreeFragSelectWrapper.java
  
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.5.2.1   +16 -0     xml-xalan/java/src/org/apache/xpath/operations/And.java
  
  Index: And.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/And.java,v
  retrieving revision 1.5
  retrieving revision 1.5.2.1
  diff -u -r1.5 -r1.5.2.1
  --- And.java	2001/01/02 03:47:18	1.5
  +++ And.java	2001/06/11 20:17:04	1.5.2.1
  @@ -95,4 +95,20 @@
       else
         return XBoolean.S_FALSE;
     }
  +  
  +  /**
  +   * Evaluate this operation directly to a boolean.
  +   *
  +   * @param xctxt The runtime execution context.
  +   *
  +   * @return The result of the operation as a boolean.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public boolean bool(XPathContext xctxt)
  +          throws javax.xml.transform.TransformerException
  +  {
  +    return (m_left.bool(xctxt) && m_right.bool(xctxt));
  +  }
  +
   }
  
  
  
  1.4.2.1   +17 -0     xml-xalan/java/src/org/apache/xpath/operations/Bool.java
  
  Index: Bool.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/Bool.java,v
  retrieving revision 1.4
  retrieving revision 1.4.2.1
  diff -u -r1.4 -r1.4.2.1
  --- Bool.java	2000/12/17 05:21:14	1.4
  +++ Bool.java	2001/06/11 20:17:04	1.4.2.1
  @@ -58,6 +58,7 @@
   
   import org.apache.xpath.objects.XObject;
   import org.apache.xpath.objects.XBoolean;
  +import org.apache.xpath.XPathContext;
   
   /**
    * The 'boolean()' operation expression executer.
  @@ -83,4 +84,20 @@
       else
         return right.bool() ? XBoolean.S_TRUE : XBoolean.S_FALSE;
     }
  +  
  +  /**
  +   * Evaluate this operation directly to a boolean.
  +   *
  +   * @param xctxt The runtime execution context.
  +   *
  +   * @return The result of the operation as a boolean.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public boolean bool(XPathContext xctxt)
  +          throws javax.xml.transform.TransformerException
  +  {
  +    return m_right.bool(xctxt);
  +  }
  +
   }
  
  
  
  1.4.2.1   +18 -0     xml-xalan/java/src/org/apache/xpath/operations/Div.java
  
  Index: Div.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/Div.java,v
  retrieving revision 1.4
  retrieving revision 1.4.2.1
  diff -u -r1.4 -r1.4.2.1
  --- Div.java	2000/12/17 05:21:15	1.4
  +++ Div.java	2001/06/11 20:17:04	1.4.2.1
  @@ -58,6 +58,7 @@
   
   import org.apache.xpath.objects.XObject;
   import org.apache.xpath.objects.XNumber;
  +import org.apache.xpath.XPathContext;
   
   /**
    * The 'div' operation expression executer.
  @@ -81,4 +82,21 @@
     {
       return new XNumber(left.num() / right.num());
     }
  +  
  +  /**
  +   * Evaluate this operation directly to a double.
  +   *
  +   * @param xctxt The runtime execution context.
  +   *
  +   * @return The result of the operation as a double.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public double num(XPathContext xctxt)
  +          throws javax.xml.transform.TransformerException
  +  {
  +
  +    return (m_left.num(xctxt) / m_right.num(xctxt));
  +  }
  +
   }
  
  
  
  1.4.2.1   +18 -0     xml-xalan/java/src/org/apache/xpath/operations/Minus.java
  
  Index: Minus.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/Minus.java,v
  retrieving revision 1.4
  retrieving revision 1.4.2.1
  diff -u -r1.4 -r1.4.2.1
  --- Minus.java	2000/12/17 05:21:16	1.4
  +++ Minus.java	2001/06/11 20:17:04	1.4.2.1
  @@ -58,6 +58,7 @@
   
   import org.apache.xpath.objects.XObject;
   import org.apache.xpath.objects.XNumber;
  +import org.apache.xpath.XPathContext;
   
   /**
    * The binary '-' operation expression executer.
  @@ -82,4 +83,21 @@
     {
       return new XNumber(left.num() - right.num());
     }
  +  
  +  /**
  +   * Evaluate this operation directly to a double.
  +   *
  +   * @param xctxt The runtime execution context.
  +   *
  +   * @return The result of the operation as a double.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public double num(XPathContext xctxt)
  +          throws javax.xml.transform.TransformerException
  +  {
  +
  +    return (m_left.num(xctxt) - m_right.num(xctxt));
  +  }
  +
   }
  
  
  
  1.4.2.1   +18 -0     xml-xalan/java/src/org/apache/xpath/operations/Mod.java
  
  Index: Mod.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/Mod.java,v
  retrieving revision 1.4
  retrieving revision 1.4.2.1
  diff -u -r1.4 -r1.4.2.1
  --- Mod.java	2000/12/17 05:21:16	1.4
  +++ Mod.java	2001/06/11 20:17:05	1.4.2.1
  @@ -58,6 +58,7 @@
   
   import org.apache.xpath.objects.XObject;
   import org.apache.xpath.objects.XNumber;
  +import org.apache.xpath.XPathContext;
   
   /**
    * The 'mod' operation expression executer.
  @@ -81,4 +82,21 @@
     {
       return new XNumber(left.num() % right.num());
     }
  +  
  +  /**
  +   * Evaluate this operation directly to a double.
  +   *
  +   * @param xctxt The runtime execution context.
  +   *
  +   * @return The result of the operation as a double.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public double num(XPathContext xctxt)
  +          throws javax.xml.transform.TransformerException
  +  {
  +
  +    return (m_left.num(xctxt) % m_right.num(xctxt));
  +  }
  +
   }
  
  
  
  1.4.2.1   +17 -0     xml-xalan/java/src/org/apache/xpath/operations/Mult.java
  
  Index: Mult.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/Mult.java,v
  retrieving revision 1.4
  retrieving revision 1.4.2.1
  diff -u -r1.4 -r1.4.2.1
  --- Mult.java	2000/12/17 05:21:16	1.4
  +++ Mult.java	2001/06/11 20:17:05	1.4.2.1
  @@ -58,6 +58,7 @@
   
   import org.apache.xpath.objects.XObject;
   import org.apache.xpath.objects.XNumber;
  +import org.apache.xpath.XPathContext;
   
   /**
    * The '*' operation expression executer.
  @@ -81,4 +82,20 @@
     {
       return new XNumber(left.num() * right.num());
     }
  +  
  +  /**
  +   * Evaluate this operation directly to a double.
  +   *
  +   * @param xctxt The runtime execution context.
  +   *
  +   * @return The result of the operation as a double.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public double num(XPathContext xctxt)
  +          throws javax.xml.transform.TransformerException
  +  {
  +    return (m_left.num(xctxt) * m_right.num(xctxt));
  +  }
  +
   }
  
  
  
  1.4.2.1   +18 -0     xml-xalan/java/src/org/apache/xpath/operations/Neg.java
  
  Index: Neg.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/Neg.java,v
  retrieving revision 1.4
  retrieving revision 1.4.2.1
  diff -u -r1.4 -r1.4.2.1
  --- Neg.java	2000/12/17 05:21:16	1.4
  +++ Neg.java	2001/06/11 20:17:05	1.4.2.1
  @@ -58,6 +58,7 @@
   
   import org.apache.xpath.objects.XObject;
   import org.apache.xpath.objects.XNumber;
  +import org.apache.xpath.XPathContext;
   
   /**
    * The unary '-' operation expression executer.
  @@ -79,4 +80,21 @@
     {
       return new XNumber(-right.num());
     }
  +  
  +  /**
  +   * Evaluate this operation directly to a double.
  +   *
  +   * @param xctxt The runtime execution context.
  +   *
  +   * @return The result of the operation as a double.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public double num(XPathContext xctxt)
  +          throws javax.xml.transform.TransformerException
  +  {
  +
  +    return -(m_right.num(xctxt));
  +  }
  +
   }
  
  
  
  1.4.2.1   +18 -0     xml-xalan/java/src/org/apache/xpath/operations/Number.java
  
  Index: Number.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/Number.java,v
  retrieving revision 1.4
  retrieving revision 1.4.2.1
  diff -u -r1.4 -r1.4.2.1
  --- Number.java	2000/12/17 05:21:17	1.4
  +++ Number.java	2001/06/11 20:17:06	1.4.2.1
  @@ -58,6 +58,7 @@
   
   import org.apache.xpath.objects.XObject;
   import org.apache.xpath.objects.XNumber;
  +import org.apache.xpath.XPathContext;
   
   /**
    * The 'number()' operation expression executer.
  @@ -83,4 +84,21 @@
       else
         return new XNumber(right.num());
     }
  +  
  +  /**
  +   * Evaluate this operation directly to a double.
  +   *
  +   * @param xctxt The runtime execution context.
  +   *
  +   * @return The result of the operation as a double.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public double num(XPathContext xctxt)
  +          throws javax.xml.transform.TransformerException
  +  {
  +
  +    return m_right.num(xctxt);
  +  }
  +
   }
  
  
  
  1.6.2.1   +17 -0     xml-xalan/java/src/org/apache/xpath/operations/Operation.java
  
  Index: Operation.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/Operation.java,v
  retrieving revision 1.6
  retrieving revision 1.6.2.1
  diff -u -r1.6 -r1.6.2.1
  --- Operation.java	2001/01/02 03:47:18	1.6
  +++ Operation.java	2001/06/11 20:17:06	1.6.2.1
  @@ -76,6 +76,23 @@
     /** The right operand expression.
      *  @serial */
     protected Expression m_right;
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    m_left.fixupVariables(vars, globalsSize);
  +    m_right.fixupVariables(vars, globalsSize);
  +  }
  +
   
     /**
      * Tell if this expression or it's subexpressions can traverse outside
  
  
  
  1.5.2.1   +16 -0     xml-xalan/java/src/org/apache/xpath/operations/Or.java
  
  Index: Or.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/Or.java,v
  retrieving revision 1.5
  retrieving revision 1.5.2.1
  diff -u -r1.5 -r1.5.2.1
  --- Or.java	2001/01/02 03:47:18	1.5
  +++ Or.java	2001/06/11 20:17:06	1.5.2.1
  @@ -95,4 +95,20 @@
       else
         return XBoolean.S_TRUE;
     }
  +  
  +  /**
  +   * Evaluate this operation directly to a boolean.
  +   *
  +   * @param xctxt The runtime execution context.
  +   *
  +   * @return The result of the operation as a boolean.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public boolean bool(XPathContext xctxt)
  +          throws javax.xml.transform.TransformerException
  +  {
  +    return (m_left.bool(xctxt) || m_right.bool(xctxt));
  +  }
  +
   }
  
  
  
  1.4.2.1   +18 -0     xml-xalan/java/src/org/apache/xpath/operations/Plus.java
  
  Index: Plus.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/Plus.java,v
  retrieving revision 1.4
  retrieving revision 1.4.2.1
  diff -u -r1.4 -r1.4.2.1
  --- Plus.java	2000/12/17 05:21:17	1.4
  +++ Plus.java	2001/06/11 20:17:06	1.4.2.1
  @@ -58,6 +58,7 @@
   
   import org.apache.xpath.objects.XObject;
   import org.apache.xpath.objects.XNumber;
  +import org.apache.xpath.XPathContext;
   
   /**
    * The '+' operation expression executer.
  @@ -81,4 +82,21 @@
     {
       return new XNumber(left.num() + right.num());
     }
  +  
  +  /**
  +   * Evaluate this operation directly to a double.
  +   *
  +   * @param xctxt The runtime execution context.
  +   *
  +   * @return The result of the operation as a double.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public double num(XPathContext xctxt)
  +          throws javax.xml.transform.TransformerException
  +  {
  +
  +    return (m_right.num(xctxt) + m_left.num(xctxt));
  +  }
  +
   }
  
  
  
  1.4.2.1   +1 -5      xml-xalan/java/src/org/apache/xpath/operations/String.java
  
  Index: String.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/String.java,v
  retrieving revision 1.4
  retrieving revision 1.4.2.1
  diff -u -r1.4 -r1.4.2.1
  --- String.java	2000/12/17 05:21:17	1.4
  +++ String.java	2001/06/11 20:17:07	1.4.2.1
  @@ -77,10 +77,6 @@
      */
     public XObject operate(XObject right) throws javax.xml.transform.TransformerException
     {
  -
  -    if (XObject.CLASS_STRING == right.getType())
  -      return right;
  -    else
  -      return new XString(right.str());
  +    return (XString)right.xstr(); // semi-safe cast.
     }
   }
  
  
  
  1.6.2.1   +16 -3     xml-xalan/java/src/org/apache/xpath/operations/UnaryOperation.java
  
  Index: UnaryOperation.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/UnaryOperation.java,v
  retrieving revision 1.6
  retrieving revision 1.6.2.1
  diff -u -r1.6 -r1.6.2.1
  --- UnaryOperation.java	2001/01/02 03:47:18	1.6
  +++ UnaryOperation.java	2001/06/11 20:17:07	1.6.2.1
  @@ -74,6 +74,21 @@
     protected Expression m_right;
     
     /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    m_right.fixupVariables(vars, globalsSize);
  +  }
  +  
  +  /**
      * Tell if this expression or it's subexpressions can traverse outside
      * the current subtree.
      *
  @@ -113,10 +128,8 @@
      */
     public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
     {
  -
  -    XObject right = m_right.execute(xctxt);
   
  -    return operate(right);
  +    return operate(m_right.execute(xctxt));
     }
   
     /**
  
  
  
  1.9.2.2   +55 -12    xml-xalan/java/src/org/apache/xpath/operations/Variable.java
  
  Index: Variable.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/operations/Variable.java,v
  retrieving revision 1.9.2.1
  retrieving revision 1.9.2.2
  diff -u -r1.9.2.1 -r1.9.2.2
  --- Variable.java	2001/05/06 02:09:56	1.9.2.1
  +++ Variable.java	2001/06/11 20:17:07	1.9.2.2
  @@ -76,7 +76,55 @@
     /** The qualified name of the variable.
      *  @serial   */
     protected QName m_qname;
  +  
  +  /**
  +   * The index of the variable, which is either an absolute index to a 
  +   * global, or, if higher than the globals area, must be adjusted by adding 
  +   * the offset to the current stack frame.
  +   */
  +  protected int m_index;
  +  
  +  protected boolean m_isGlobal = false;
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    int sz = vars.size();
  +    for (int i = vars.size()-1; i >= 0; i--) 
  +    {
  +      QName qn = (QName)vars.elementAt(i);
  +      // System.out.println("qn: "+qn);
  +      if(qn.equals(m_qname))
  +      {
  +        
  +        if(i < globalsSize)
  +        {
  +          m_isGlobal = true;
  +          m_index = i;
  +        }
  +        else
  +        {
  +          m_index = i-globalsSize;
  +        }
  +          
  +        return;
  +      }
  +    }
  +    throw new RuntimeException("Could not find variable with the name of "
  +                                +m_qname.toString()+"!");
  +    
  +  }
   
  +
     /**
      * Set the qualified name of the variable.
      *
  @@ -103,22 +151,17 @@
     {
   
       // Is the variable fetched always the same?
  +    // XObject result = xctxt.getVariable(m_qname);
  +    
       XObject result;
  -
  -//    try
  -//    {
  -      result = xctxt.getVariable(m_qname);
  -//    }
  -//    catch (Exception e)
  -//    {
  -//      error(xctxt, XPATHErrorResources.ER_COULDNOT_GET_VAR_NAMED,
  -//            new Object[]{ m_qname.getLocalPart() });  //"Could not get variable named "+varName);
  -//
  -//      result = null;
  -//    }
  +    if(m_isGlobal)
  +      result = xctxt.getVarStack().getGlobalVariable(xctxt, m_index);
  +    else
  +      result = xctxt.getVarStack().getLocalVariable(xctxt, m_index);
   
       if (null == result)
       {
  +      // This should now never happen...
         warn(xctxt, XPATHErrorResources.WG_ILLEGAL_VARIABLE_REFERENCE,
              new Object[]{ m_qname.getLocalPart() });  //"VariableReference given for variable out "+
   //      (new RuntimeException()).printStackTrace();
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.7.2.9   +17 -0     xml-xalan/java/src/org/apache/xpath/patterns/FunctionPattern.java
  
  Index: FunctionPattern.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/patterns/FunctionPattern.java,v
  retrieving revision 1.7.2.8
  retrieving revision 1.7.2.9
  diff -u -r1.7.2.8 -r1.7.2.9
  --- FunctionPattern.java	2001/06/04 21:25:53	1.7.2.8
  +++ FunctionPattern.java	2001/06/11 20:17:14	1.7.2.9
  @@ -108,6 +108,23 @@
     Expression m_functionExpr;
     
     /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    super.fixupVariables(vars, globalsSize);
  +    m_functionExpr.fixupVariables(vars, globalsSize);
  +  }
  +
  +  
  +  /**
      * Test a node to see if it matches the given node test.
      *
      * @param xctxt XPath runtime context.
  
  
  
  1.20.2.9  +9 -0      xml-xalan/java/src/org/apache/xpath/patterns/NodeTest.java
  
  Index: NodeTest.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/patterns/NodeTest.java,v
  retrieving revision 1.20.2.8
  retrieving revision 1.20.2.9
  diff -u -r1.20.2.8 -r1.20.2.9
  --- NodeTest.java	2001/06/04 07:53:00	1.20.2.8
  +++ NodeTest.java	2001/06/11 20:17:15	1.20.2.9
  @@ -670,4 +670,13 @@
     {
       return execute(xctxt, xctxt.getCurrentNode());
     }
  +  
  +  /**
  +   * Node tests by themselves do not need to fix up variables.
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    // no-op
  +  }
  +
   }
  
  
  
  1.19.2.8  +27 -0     xml-xalan/java/src/org/apache/xpath/patterns/StepPattern.java
  
  Index: StepPattern.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/patterns/StepPattern.java,v
  retrieving revision 1.19.2.7
  retrieving revision 1.19.2.8
  diff -u -r1.19.2.7 -r1.19.2.8
  --- StepPattern.java	2001/06/04 07:53:01	1.19.2.7
  +++ StepPattern.java	2001/06/11 20:17:15	1.19.2.8
  @@ -179,6 +179,33 @@
      * @serial
      */
     StepPattern m_relativePathPattern;
  +  
  +  /**
  +   * This function is used to fixup variables from QNames to stack frame 
  +   * indexes at stylesheet build time.
  +   * @param vars List of QNames that correspond to variables.  This list 
  +   * should be searched backwards for the first qualified name that 
  +   * corresponds to the variable reference qname.  The position of the 
  +   * QName in the vector from the start of the vector will be its position 
  +   * in the stack frame (but variables above the globalsTop value will need 
  +   * to be offset to the current stack frame).
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    super.fixupVariables(vars, globalsSize);
  +    if(null != m_predicates)
  +    {
  +      for (int i = 0; i < m_predicates.length; i++) 
  +      {
  +        m_predicates[i].fixupVariables(vars, globalsSize);
  +      }
  +    }
  +    if(null != m_relativePathPattern)
  +    {
  +      m_relativePathPattern.fixupVariables(vars, globalsSize);
  +    }
  +  }
  +
   
     /**
      * Set the reference to nodetest and predicate for
  
  
  
  1.7.2.1   +12 -0     xml-xalan/java/src/org/apache/xpath/patterns/UnionPattern.java
  
  Index: UnionPattern.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/patterns/UnionPattern.java,v
  retrieving revision 1.7
  retrieving revision 1.7.2.1
  diff -u -r1.7 -r1.7.2.1
  --- UnionPattern.java	2001/01/02 03:47:19	1.7
  +++ UnionPattern.java	2001/06/11 20:17:16	1.7.2.1
  @@ -73,6 +73,18 @@
     private StepPattern[] m_patterns;
     
     /**
  +   * No arguments to process, so this does nothing.
  +   */
  +  public void fixupVariables(java.util.Vector vars, int globalsSize)
  +  {
  +    for (int i = 0; i < m_patterns.length; i++) 
  +    {
  +      m_patterns[i].fixupVariables(vars, globalsSize);
  +    }
  +  }
  +
  +  
  +  /**
      * Tell if this expression or it's subexpressions can traverse outside 
      * the current subtree.
      * 
  
  
  

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