/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * Copyright 1999-2019 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: WalkerFactory.java,v 1.2.4.1 2005/09/10 03:42:19 jeffsuttor Exp $
 */
package com.sun.org.apache.xpath.internal.axes;

import com.sun.org.apache.xalan.internal.res.XSLMessages;
import com.sun.org.apache.xml.internal.dtm.Axis;
import com.sun.org.apache.xml.internal.dtm.DTMFilter;
import com.sun.org.apache.xml.internal.dtm.DTMIterator;
import com.sun.org.apache.xpath.internal.Expression;
import com.sun.org.apache.xpath.internal.compiler.Compiler;
import com.sun.org.apache.xpath.internal.compiler.FunctionTable;
import com.sun.org.apache.xpath.internal.compiler.OpCodes;
import com.sun.org.apache.xpath.internal.compiler.OpMap;
import com.sun.org.apache.xpath.internal.objects.XNumber;
import com.sun.org.apache.xpath.internal.patterns.ContextMatchStepPattern;
import com.sun.org.apache.xpath.internal.patterns.FunctionPattern;
import com.sun.org.apache.xpath.internal.patterns.NodeTest;
import com.sun.org.apache.xpath.internal.patterns.StepPattern;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;

/**
 * This class is both a factory for XPath location path expressions,
 * which are built from the opcode map output, and an analysis engine
 * for the location path expressions in order to provide optimization hints.
 */
public class WalkerFactory
{

  /**
   * This method is for building an array of possible levels
   * where the target element(s) could be found for a match.
   * @param lpi The owning location path iterator.
   * @param compiler non-null reference to compiler object that has processed
   *                 the XPath operations into an opcode map.
   * @param stepOpCodePos The opcode position for the step.
   *
   * @return non-null AxesWalker derivative.
   *
   * @throws javax.xml.transform.TransformerException
   * @xsl.usage advanced
   */
  static AxesWalker loadOneWalker(
          WalkingIterator lpi, Compiler compiler, int stepOpCodePos)
            throws javax.xml.transform.TransformerException
  {

    AxesWalker firstWalker = null;
    int stepType = compiler.getOp(stepOpCodePos);

    if (stepType != OpCodes.ENDOP)
    {

      // m_axesWalkers = new AxesWalker[1];
      // As we unwind from the recursion, create the iterators.
      firstWalker = createDefaultWalker(compiler, stepType, lpi, 0);

      firstWalker.init(compiler, stepOpCodePos, stepType);
    }

    return firstWalker;
  }

  /**
   * This method is for building an array of possible levels
   * where the target element(s) could be found for a match.
   * @param lpi The owning location path iterator object.
   * @param compiler non-null reference to compiler object that has processed
   *                 the XPath operations into an opcode map.
   * @param stepOpCodePos The opcode position for the step.
   * @param stepIndex The top-level step index withing the iterator.
   *
   * @return non-null AxesWalker derivative.
   *
   * @throws javax.xml.transform.TransformerException
   * @xsl.usage advanced
   */
  static AxesWalker loadWalkers(
          WalkingIterator lpi, Compiler compiler, int stepOpCodePos, int stepIndex)
            throws javax.xml.transform.TransformerException
  {

    int stepType;
    AxesWalker firstWalker = null;
    AxesWalker walker, prevWalker = null;

    int analysis = analyze(compiler, stepOpCodePos, stepIndex);

    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
    {
      walker = createDefaultWalker(compiler, stepOpCodePos, lpi, analysis);

      walker.init(compiler, stepOpCodePos, stepType);
      walker.exprSetParent(lpi);

      // walker.setAnalysis(analysis);
      if (null == firstWalker)
      {
        firstWalker = walker;
      }
      else
      {
        prevWalker.setNextWalker(walker);
        walker.setPrevWalker(prevWalker);
      }

      prevWalker = walker;
      stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);

      if (stepOpCodePos < 0)
        break;
    }

    return firstWalker;
  }

  public static boolean isSet(int analysis, int bits)
  {
    return (0 != (analysis & bits));
  }

  public static void diagnoseIterator(String name, int analysis, Compiler compiler)
  {
    System.out.println(compiler.toString()+", "+name+", "
                             + Integer.toBinaryString(analysis) + ", "
                             + getAnalysisString(analysis));
  }

  /**
   * Create a new LocPathIterator iterator.  The exact type of iterator
   * returned is based on an analysis of the XPath operations.
   *
   * @param compiler non-null reference to compiler object that has processed
   *                 the XPath operations into an opcode map.
   * @param opPos The position of the operation code for this itterator.
   *
   * @return non-null reference to a LocPathIterator or derivative.
   *
   * @throws javax.xml.transform.TransformerException
   */
  public static DTMIterator newDTMIterator(
          Compiler compiler, int opPos,
          boolean isTopLevel)
            throws javax.xml.transform.TransformerException
  {

    int firstStepPos = OpMap.getFirstChildPos(opPos);
    int analysis = analyze(compiler, firstStepPos, 0);
    boolean isOneStep = isOneStep(analysis);
    DTMIterator iter;

    // Is the iteration a one-step attribute pattern (i.e. select="@foo")?
    if (isOneStep && walksSelfOnly(analysis) &&
        isWild(analysis) && !hasPredicate(analysis))
    {
      if (DEBUG_ITERATOR_CREATION)
        diagnoseIterator("SelfIteratorNoPredicate", analysis, compiler);

      // Then use a simple iteration of the attributes, with node test
      // and predicate testing.
      iter = new SelfIteratorNoPredicate(compiler, opPos, analysis);
    }
    // Is the iteration exactly one child step?
    else if (walksChildrenOnly(analysis) && isOneStep)
    {

      // Does the pattern specify *any* child with no predicate? (i.e. select="child::node()".
      if (isWild(analysis) && !hasPredicate(analysis))
      {
        if (DEBUG_ITERATOR_CREATION)
          diagnoseIterator("ChildIterator", analysis, compiler);

        // Use simple child iteration without any test.
        iter = new ChildIterator(compiler, opPos, analysis);
      }
      else
      {
        if (DEBUG_ITERATOR_CREATION)
          diagnoseIterator("ChildTestIterator", analysis, compiler);

        // Else use simple node test iteration with predicate test.
        iter = new ChildTestIterator(compiler, opPos, analysis);
      }
    }
    // Is the iteration a one-step attribute pattern (i.e. select="@foo")?
    else if (isOneStep && walksAttributes(analysis))
    {
      if (DEBUG_ITERATOR_CREATION)
        diagnoseIterator("AttributeIterator", analysis, compiler);

      // Then use a simple iteration of the attributes, with node test
      // and predicate testing.
      iter = new AttributeIterator(compiler, opPos, analysis);
    }
    else if(isOneStep && !walksFilteredList(analysis))
    {
      if( !walksNamespaces(analysis)
      && (walksInDocOrder(analysis) || isSet(analysis, BIT_PARENT)))
      {
        if (false || DEBUG_ITERATOR_CREATION)
          diagnoseIterator("OneStepIteratorForward", analysis, compiler);

        // Then use a simple iteration of the attributes, with node test
        // and predicate testing.
        iter = new OneStepIteratorForward(compiler, opPos, analysis);
      }
      else
      {
        if (false || DEBUG_ITERATOR_CREATION)
          diagnoseIterator("OneStepIterator", analysis, compiler);

        // Then use a simple iteration of the attributes, with node test
        // and predicate testing.
        iter = new OneStepIterator(compiler, opPos, analysis);
      }
    }

    // Analysis of "//center":
    // bits: 1001000000001010000000000000011
    // count: 3
    // root
    // child:node()
    // BIT_DESCENDANT_OR_SELF
    // It's highly possible that we should have a seperate bit set for
    // "//foo" patterns.
    // For at least the time being, we can't optimize patterns like
    // "//table[3]", because this has to be analyzed as
    // "/descendant-or-self::node()/table[3]" in order for the indexes
    // to work right.
    else if (isOptimizableForDescendantIterator(compiler, firstStepPos, 0)
              // && getStepCount(analysis) <= 3
              // && walksDescendants(analysis)
              // && walksSubtreeOnlyFromRootOrContext(analysis)
             )
    {
      if (DEBUG_ITERATOR_CREATION)
        diagnoseIterator("DescendantIterator", analysis, compiler);

      iter = new DescendantIterator(compiler, opPos, analysis);
    }
    else
    {
      if(isNaturalDocOrder(compiler, firstStepPos, 0, analysis))
      {
        if (false || DEBUG_ITERATOR_CREATION)
        {
          diagnoseIterator("WalkingIterator", analysis, compiler);
        }

        iter = new WalkingIterator(compiler, opPos, analysis, true);
      }
      else
      {
//        if (DEBUG_ITERATOR_CREATION)
//          diagnoseIterator("MatchPatternIterator", analysis, compiler);
//
//        return new MatchPatternIterator(compiler, opPos, analysis);
        if (DEBUG_ITERATOR_CREATION)
          diagnoseIterator("WalkingIteratorSorted", analysis, compiler);

        iter = new WalkingIteratorSorted(compiler, opPos, analysis, true);
      }
    }
    if(iter instanceof LocPathIterator)
      ((LocPathIterator)iter).setIsTopLevel(isTopLevel);

    return iter;
  }

  /**
   * Special purpose function to see if we can optimize the pattern for
   * a DescendantIterator.
   *
   * @param compiler non-null reference to compiler object that has processed
   *                 the XPath operations into an opcode map.
   * @param stepOpCodePos The opcode position for the step.
   *
   * @return 32 bits as an integer that give information about the location
   * path as a whole.
   *
   * @throws javax.xml.transform.TransformerException
   */
  public static int getAxisFromStep(
          Compiler compiler, int stepOpCodePos)
            throws javax.xml.transform.TransformerException
  {

    int stepType = compiler.getOp(stepOpCodePos);

    switch (stepType)
    {
    case OpCodes.FROM_FOLLOWING :
      return Axis.FOLLOWING;
    case OpCodes.FROM_FOLLOWING_SIBLINGS :
      return Axis.FOLLOWINGSIBLING;
    case OpCodes.FROM_PRECEDING :
      return Axis.PRECEDING;
    case OpCodes.FROM_PRECEDING_SIBLINGS :
      return Axis.PRECEDINGSIBLING;
    case OpCodes.FROM_PARENT :
      return Axis.PARENT;
    case OpCodes.FROM_NAMESPACE :
      return Axis.NAMESPACE;
    case OpCodes.FROM_ANCESTORS :
      return Axis.ANCESTOR;
    case OpCodes.FROM_ANCESTORS_OR_SELF :
      return Axis.ANCESTORORSELF;
    case OpCodes.FROM_ATTRIBUTES :
      return Axis.ATTRIBUTE;
    case OpCodes.FROM_ROOT :
      return Axis.ROOT;
    case OpCodes.FROM_CHILDREN :
      return Axis.CHILD;
    case OpCodes.FROM_DESCENDANTS_OR_SELF :
      return Axis.DESCENDANTORSELF;
    case OpCodes.FROM_DESCENDANTS :
      return Axis.DESCENDANT;
    case OpCodes.FROM_SELF :
      return Axis.SELF;
    case OpCodes.OP_EXTFUNCTION :
    case OpCodes.OP_FUNCTION :
    case OpCodes.OP_GROUP :
    case OpCodes.OP_VARIABLE :
      return Axis.FILTEREDLIST;
    }

    throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
                               //+ stepType);
   }

    /**
     * Get a corresponding BIT_XXX from an axis.
     * @param axis One of Axis.ANCESTOR, etc.
     * @return One of BIT_ANCESTOR, etc.
     */
    static public int getAnalysisBitFromAxes(int axis)
    {
      switch (axis) // Generate new traverser
        {
        case Axis.ANCESTOR :
          return BIT_ANCESTOR;
        case Axis.ANCESTORORSELF :
          return BIT_ANCESTOR_OR_SELF;
        case Axis.ATTRIBUTE :
          return BIT_ATTRIBUTE;
        case Axis.CHILD :
          return BIT_CHILD;
        case Axis.DESCENDANT :
          return BIT_DESCENDANT;
        case Axis.DESCENDANTORSELF :
          return BIT_DESCENDANT_OR_SELF;
        case Axis.FOLLOWING :
          return BIT_FOLLOWING;
        case Axis.FOLLOWINGSIBLING :
          return BIT_FOLLOWING_SIBLING;
        case Axis.NAMESPACE :
        case Axis.NAMESPACEDECLS :
          return BIT_NAMESPACE;
        case Axis.PARENT :
          return BIT_PARENT;
        case Axis.PRECEDING :
          return BIT_PRECEDING;
        case Axis.PRECEDINGSIBLING :
          return BIT_PRECEDING_SIBLING;
        case Axis.SELF :
          return BIT_SELF;
        case Axis.ALLFROMNODE :
          return BIT_DESCENDANT_OR_SELF;
          // case Axis.PRECEDINGANDANCESTOR :
        case Axis.DESCENDANTSFROMROOT :
        case Axis.ALL :
        case Axis.DESCENDANTSORSELFFROMROOT :
          return BIT_ANY_DESCENDANT_FROM_ROOT;
        case Axis.ROOT :
          return BIT_ROOT;
        case Axis.FILTEREDLIST :
          return BIT_FILTER;
        default :
          return BIT_FILTER;
      }
    }

  static boolean functionProximateOrContainsProximate(Compiler compiler,
                                                      int opPos)
  {
    int endFunc = opPos + compiler.getOp(opPos + 1) - 1;
    opPos = OpMap.getFirstChildPos(opPos);
    int funcID = compiler.getOp(opPos);
    //  System.out.println("funcID: "+funcID);
    //  System.out.println("opPos: "+opPos);
    //  System.out.println("endFunc: "+endFunc);
    switch(funcID)
    {
      case FunctionTable.FUNC_LAST:
      case FunctionTable.FUNC_POSITION:
        return true;
      default:
        opPos++;
        int i = 0;
        for (int p = opPos; p < endFunc; p = compiler.getNextOpPos(p), i++)
        {
          int innerExprOpPos = p+2;
          int argOp = compiler.getOp(innerExprOpPos);
          boolean prox = isProximateInnerExpr(compiler, innerExprOpPos);
          if(prox)
            return true;
        }

    }
    return false;
  }

  static boolean isProximateInnerExpr(Compiler compiler, int opPos)
  {
    int op = compiler.getOp(opPos);
    int innerExprOpPos = opPos+2;
    switch(op)
    {
      case OpCodes.OP_ARGUMENT:
        if(isProximateInnerExpr(compiler, innerExprOpPos))
          return true;
        break;
      case OpCodes.OP_VARIABLE:
      case OpCodes.OP_NUMBERLIT:
      case OpCodes.OP_LITERAL:
      case OpCodes.OP_LOCATIONPATH:
        break; // OK
      case OpCodes.OP_FUNCTION:
        boolean isProx = functionProximateOrContainsProximate(compiler, opPos);
        if(isProx)
          return true;
        break;
      case OpCodes.OP_GT:
      case OpCodes.OP_GTE:
      case OpCodes.OP_LT:
      case OpCodes.OP_LTE:
      case OpCodes.OP_EQUALS:
        int leftPos = OpMap.getFirstChildPos(op);
        int rightPos = compiler.getNextOpPos(leftPos);
        isProx = isProximateInnerExpr(compiler, leftPos);
        if(isProx)
          return true;
        isProx = isProximateInnerExpr(compiler, rightPos);
        if(isProx)
          return true;
        break;
      default:
        return true; // be conservative...
    }
    return false;
  }

  /**
   * Tell if the predicates need to have proximity knowledge.
   */
  public static boolean mightBeProximate(Compiler compiler, int opPos, int stepType)
          throws javax.xml.transform.TransformerException
  {

    boolean mightBeProximate = false;
    int argLen;

    switch (stepType)
    {
    case OpCodes.OP_VARIABLE :
    case OpCodes.OP_EXTFUNCTION :
    case OpCodes.OP_FUNCTION :
    case OpCodes.OP_GROUP :
      argLen = compiler.getArgLength(opPos);
      break;
    default :
      argLen = compiler.getArgLengthOfStep(opPos);
    }

    int predPos = compiler.getFirstPredicateOpPos(opPos);
    int count = 0;

    while (OpCodes.OP_PREDICATE == compiler.getOp(predPos))
    {
      count++;

      int innerExprOpPos = predPos+2;
      int predOp = compiler.getOp(innerExprOpPos);

      switch(predOp)
      {
        case OpCodes.OP_VARIABLE:
                return true; // Would need more smarts to tell if this could be a number or not!
        case OpCodes.OP_LOCATIONPATH:
          // OK.
          break;
        case OpCodes.OP_NUMBER:
        case OpCodes.OP_NUMBERLIT:
          return true; // that's all she wrote!
        case OpCodes.OP_FUNCTION:
          boolean isProx
            = functionProximateOrContainsProximate(compiler, innerExprOpPos);
          if(isProx)
            return true;
          break;
        case OpCodes.OP_GT:
        case OpCodes.OP_GTE:
        case OpCodes.OP_LT:
        case OpCodes.OP_LTE:
        case OpCodes.OP_EQUALS:
          int leftPos = OpMap.getFirstChildPos(innerExprOpPos);
          int rightPos = compiler.getNextOpPos(leftPos);
          isProx = isProximateInnerExpr(compiler, leftPos);
          if(isProx)
            return true;
          isProx = isProximateInnerExpr(compiler, rightPos);
          if(isProx)
            return true;
          break;
        default:
          return true; // be conservative...
      }

      predPos = compiler.getNextOpPos(predPos);
    }

    return mightBeProximate;
  }

  /**
   * Special purpose function to see if we can optimize the pattern for
   * a DescendantIterator.
   *
   * @param compiler non-null reference to compiler object that has processed
   *                 the XPath operations into an opcode map.
   * @param stepOpCodePos The opcode position for the step.
   * @param stepIndex The top-level step index withing the iterator.
   *
   * @return 32 bits as an integer that give information about the location
   * path as a whole.
   *
   * @throws javax.xml.transform.TransformerException
   */
  private static boolean isOptimizableForDescendantIterator(
          Compiler compiler, int stepOpCodePos, int stepIndex)
            throws javax.xml.transform.TransformerException
  {

    int stepType;
    int stepCount = 0;
    boolean foundDorDS = false;
    boolean foundSelf = false;
    boolean foundDS = false;

    int nodeTestType = OpCodes.NODETYPE_NODE;

    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
    {
      // The DescendantIterator can only do one node test.  If there's more
      // than one, use another iterator.
      if(nodeTestType != OpCodes.NODETYPE_NODE && nodeTestType != OpCodes.NODETYPE_ROOT)
        return false;

      stepCount++;
      if(stepCount > 3)
        return false;

      boolean mightBeProximate = mightBeProximate(compiler, stepOpCodePos, stepType);
      if(mightBeProximate)
        return false;

      switch (stepType)
      {
      case OpCodes.FROM_FOLLOWING :
      case OpCodes.FROM_FOLLOWING_SIBLINGS :
      case OpCodes.FROM_PRECEDING :
      case OpCodes.FROM_PRECEDING_SIBLINGS :
      case OpCodes.FROM_PARENT :
      case OpCodes.OP_VARIABLE :
      case OpCodes.OP_EXTFUNCTION :
      case OpCodes.OP_FUNCTION :
      case OpCodes.OP_GROUP :
      case OpCodes.FROM_NAMESPACE :
      case OpCodes.FROM_ANCESTORS :
      case OpCodes.FROM_ANCESTORS_OR_SELF :
      case OpCodes.FROM_ATTRIBUTES :
      case OpCodes.MATCH_ATTRIBUTE :
      case OpCodes.MATCH_ANY_ANCESTOR :
      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
        return false;
      case OpCodes.FROM_ROOT :
        if(1 != stepCount)
          return false;
        break;
      case OpCodes.FROM_CHILDREN :
        if(!foundDS && !(foundDorDS && foundSelf))
          return false;
        break;
      case OpCodes.FROM_DESCENDANTS_OR_SELF :
        foundDS = true;
      case OpCodes.FROM_DESCENDANTS :
        if(3 == stepCount)
          return false;
        foundDorDS = true;
        break;
      case OpCodes.FROM_SELF :
        if(1 != stepCount)
          return false;
        foundSelf = true;
        break;
      default :
        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
                                  // + stepType);
      }

      nodeTestType = compiler.getStepTestType(stepOpCodePos);

      int nextStepOpCodePos = compiler.getNextStepPos(stepOpCodePos);

      if (nextStepOpCodePos < 0)
        break;

      if(OpCodes.ENDOP != compiler.getOp(nextStepOpCodePos))
      {
        if(compiler.countPredicates(stepOpCodePos) > 0)
        {
          return false;
        }
      }

      stepOpCodePos = nextStepOpCodePos;
    }

    return true;
  }

  /**
   * Analyze the location path and return 32 bits that give information about
   * the location path as a whole.  See the BIT_XXX constants for meaning about
   * each of the bits.
   *
   * @param compiler non-null reference to compiler object that has processed
   *                 the XPath operations into an opcode map.
   * @param stepOpCodePos The opcode position for the step.
   * @param stepIndex The top-level step index withing the iterator.
   *
   * @return 32 bits as an integer that give information about the location
   * path as a whole.
   *
   * @throws javax.xml.transform.TransformerException
   */
  private static int analyze(
          Compiler compiler, int stepOpCodePos, int stepIndex)
            throws javax.xml.transform.TransformerException
  {

    int stepType;
    int stepCount = 0;
    int analysisResult = 0x00000000;  // 32 bits of analysis

    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
    {
      stepCount++;

      // String namespace = compiler.getStepNS(stepOpCodePos);
      // boolean isNSWild = (null != namespace)
      //                   ? namespace.equals(NodeTest.WILD) : false;
      // String localname = compiler.getStepLocalName(stepOpCodePos);
      // boolean isWild = (null != localname) ? localname.equals(NodeTest.WILD) : false;
      boolean predAnalysis = analyzePredicate(compiler, stepOpCodePos,
                                              stepType);

      if (predAnalysis)
        analysisResult |= BIT_PREDICATE;

      switch (stepType)
      {
      case OpCodes.OP_VARIABLE :
      case OpCodes.OP_EXTFUNCTION :
      case OpCodes.OP_FUNCTION :
      case OpCodes.OP_GROUP :
        analysisResult |= BIT_FILTER;
        break;
      case OpCodes.FROM_ROOT :
        analysisResult |= BIT_ROOT;
        break;
      case OpCodes.FROM_ANCESTORS :
        analysisResult |= BIT_ANCESTOR;
        break;
      case OpCodes.FROM_ANCESTORS_OR_SELF :
        analysisResult |= BIT_ANCESTOR_OR_SELF;
        break;
      case OpCodes.FROM_ATTRIBUTES :
        analysisResult |= BIT_ATTRIBUTE;
        break;
      case OpCodes.FROM_NAMESPACE :
        analysisResult |= BIT_NAMESPACE;
        break;
      case OpCodes.FROM_CHILDREN :
        analysisResult |= BIT_CHILD;
        break;
      case OpCodes.FROM_DESCENDANTS :
        analysisResult |= BIT_DESCENDANT;
        break;
      case OpCodes.FROM_DESCENDANTS_OR_SELF :

        // Use a special bit to to make sure we get the right analysis of "//foo".
        if (2 == stepCount && BIT_ROOT == analysisResult)
        {
          analysisResult |= BIT_ANY_DESCENDANT_FROM_ROOT;
        }

        analysisResult |= BIT_DESCENDANT_OR_SELF;
        break;
      case OpCodes.FROM_FOLLOWING :
        analysisResult |= BIT_FOLLOWING;
        break;
      case OpCodes.FROM_FOLLOWING_SIBLINGS :
        analysisResult |= BIT_FOLLOWING_SIBLING;
        break;
      case OpCodes.FROM_PRECEDING :
        analysisResult |= BIT_PRECEDING;
        break;
      case OpCodes.FROM_PRECEDING_SIBLINGS :
        analysisResult |= BIT_PRECEDING_SIBLING;
        break;
      case OpCodes.FROM_PARENT :
        analysisResult |= BIT_PARENT;
        break;
      case OpCodes.FROM_SELF :
        analysisResult |= BIT_SELF;
        break;
      case OpCodes.MATCH_ATTRIBUTE :
        analysisResult |= (BIT_MATCH_PATTERN | BIT_ATTRIBUTE);
        break;
      case OpCodes.MATCH_ANY_ANCESTOR :
        analysisResult |= (BIT_MATCH_PATTERN | BIT_ANCESTOR);
        break;
      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
        analysisResult |= (BIT_MATCH_PATTERN | BIT_PARENT);
        break;
      default :
        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
                                   //+ stepType);
      }

      if (OpCodes.NODETYPE_NODE == compiler.getOp(stepOpCodePos + 3))  // child::node()
      {
        analysisResult |= BIT_NODETEST_ANY;
      }

      stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);

      if (stepOpCodePos < 0)
        break;
    }

    analysisResult |= (stepCount & BITS_COUNT);

    return analysisResult;
  }

  /**
   * Tell if the given axis goes downword.  Bogus name, if you can think of
   * a better one, please do tell.  This really has to do with inverting
   * attribute axis.
   * @param axis One of Axis.XXX.
   * @return true if the axis is not a child axis and does not go up from
   * the axis root.
   */
  public static boolean isDownwardAxisOfMany(int axis)
  {
    return ((Axis.DESCENDANTORSELF == axis) ||
          (Axis.DESCENDANT == axis)
          || (Axis.FOLLOWING == axis)
//          || (Axis.FOLLOWINGSIBLING == axis)
          || (Axis.PRECEDING == axis)
//          || (Axis.PRECEDINGSIBLING == axis)
          );
  }

  /**
   * Read a <a href="http://www.w3.org/TR/xpath#location-paths">LocationPath</a>
   * as a generalized match pattern.  What this means is that the LocationPath
   * is read backwards, as a test on a given node, to see if it matches the
   * criteria of the selection, and ends up at the context node.  Essentially,
   * this is a backwards query from a given node, to find the context node.
   * <p>So, the selection "foo/daz[2]" is, in non-abreviated expanded syntax,
   * "self::node()/following-sibling::foo/child::daz[position()=2]".
   * Taking this as a match pattern for a probable node, it works out to
   * "self::daz/parent::foo[child::daz[position()=2 and isPrevStepNode()]
   * precedingSibling::node()[isContextNodeOfLocationPath()]", adding magic
   * isPrevStepNode and isContextNodeOfLocationPath operations.  Predicates in
   * the location path have to be executed by the following step,
   * because they have to know the context of their execution.
   *
   * @param mpi The MatchPatternIterator to which the steps will be attached.
   * @param compiler The compiler that holds the syntax tree/op map to
   * construct from.
   * @param stepOpCodePos The current op code position within the opmap.
   * @param stepIndex The top-level step index withing the iterator.
   *
   * @return A StepPattern object, which may contain relative StepPatterns.
   *
   * @throws javax.xml.transform.TransformerException
   */
  static StepPattern loadSteps(
          MatchPatternIterator mpi, Compiler compiler, int stepOpCodePos,
                                                       int stepIndex)
            throws javax.xml.transform.TransformerException
  {
    if (DEBUG_PATTERN_CREATION)
    {
      System.out.println("================");
      System.out.println("loadSteps for: "+compiler.getPatternString());
    }
    int stepType;
    StepPattern step = null;
    StepPattern firstStep = null, prevStep = null;
    int analysis = analyze(compiler, stepOpCodePos, stepIndex);

    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
    {
      step = createDefaultStepPattern(compiler, stepOpCodePos, mpi, analysis,
                                      firstStep, prevStep);

      if (null == firstStep)
      {
        firstStep = step;
      }
      else
      {

        //prevStep.setNextWalker(step);
        step.setRelativePathPattern(prevStep);
      }

      prevStep = step;
      stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);

      if (stepOpCodePos < 0)
        break;
    }

    int axis = Axis.SELF;
    int paxis = Axis.SELF;
    StepPattern tail = step;
    for (StepPattern pat = step; null != pat;
         pat = pat.getRelativePathPattern())
    {
      int nextAxis = pat.getAxis();
      //int nextPaxis = pat.getPredicateAxis();
      pat.setAxis(axis);

      // The predicate axis can't be moved!!!  Test Axes103
      // pat.setPredicateAxis(paxis);

      // If we have an attribute or namespace axis that went up, then
      // it won't find the attribute in the inverse, since the select-to-match
      // axes are not invertable (an element is a parent of an attribute, but
      // and attribute is not a child of an element).
      // If we don't do the magic below, then "@*/ancestor-or-self::*" gets
      // inverted for match to "self::*/descendant-or-self::@*/parent::node()",
      // which obviously won't work.
      // So we will rewrite this as:
      // "self::*/descendant-or-self::*/attribute::*/parent::node()"
      // Child has to be rewritten a little differently:
      // select: "@*/parent::*"
      // inverted match: "self::*/child::@*/parent::node()"
      // rewrite: "self::*/attribute::*/parent::node()"
      // Axes that go down in the select, do not have to have special treatment
      // in the rewrite. The following inverted match will still not select
      // anything.
      // select: "@*/child::*"
      // inverted match: "self::*/parent::@*/parent::node()"
      // Lovely business, this.
      // -sb
      int whatToShow = pat.getWhatToShow();
      if(whatToShow == DTMFilter.SHOW_ATTRIBUTE ||
         whatToShow == DTMFilter.SHOW_NAMESPACE)
      {
        int newAxis = (whatToShow == DTMFilter.SHOW_ATTRIBUTE) ?
                       Axis.ATTRIBUTE : Axis.NAMESPACE;
        if(isDownwardAxisOfMany(axis))
        {
          StepPattern attrPat = new StepPattern(whatToShow,
                                    pat.getNamespace(),
                                    pat.getLocalName(),
                                //newAxis, pat.getPredicateAxis);
                                                newAxis, 0); // don't care about the predicate axis
          XNumber score = pat.getStaticScore();
          pat.setNamespace(null);
          pat.setLocalName(NodeTest.WILD);
          attrPat.setPredicates(pat.getPredicates());
          pat.setPredicates(null);
          pat.setWhatToShow(DTMFilter.SHOW_ELEMENT);
          StepPattern rel = pat.getRelativePathPattern();
          pat.setRelativePathPattern(attrPat);
          attrPat.setRelativePathPattern(rel);
          attrPat.setStaticScore(score);

          // This is needed to inverse a following pattern, because of the
          // wacky Xalan rules for following from an attribute.  See axes108.
          // By these rules, following from an attribute is not strictly
          // inverseable.
          if(Axis.PRECEDING == pat.getAxis())
            pat.setAxis(Axis.PRECEDINGANDANCESTOR);

          else if(Axis.DESCENDANT == pat.getAxis())
            pat.setAxis(Axis.DESCENDANTORSELF);

          pat = attrPat;
        }
        else if(Axis.CHILD == pat.getAxis())
        {
          // In this case just change the axis.
          // pat.setWhatToShow(whatToShow);
          pat.setAxis(Axis.ATTRIBUTE);
        }
      }
      axis = nextAxis;
      //paxis = nextPaxis;
      tail = pat;
    }

    if(axis < Axis.ALL)
    {
      StepPattern selfPattern = new ContextMatchStepPattern(axis, paxis);
      // We need to keep the new nodetest from affecting the score...
      XNumber score = tail.getStaticScore();
      tail.setRelativePathPattern(selfPattern);
      tail.setStaticScore(score);
      selfPattern.setStaticScore(score);
    }

    if (DEBUG_PATTERN_CREATION)
    {
      System.out.println("Done loading steps: "+step.toString());

      System.out.println("");
    }
    return step;  // start from last pattern?? //firstStep;
  }

  /**
   * Create a StepPattern that is contained within a LocationPath.
   *
   *
   * @param compiler The compiler that holds the syntax tree/op map to
   * construct from.
   * @param stepOpCodePos The current op code position within the opmap.
   * @param mpi The MatchPatternIterator to which the steps will be attached.
   * @param analysis 32 bits of analysis, from which the type of AxesWalker
   *                 may be influenced.
   * @param tail The step that is the first step analyzed, but the last
   *                  step in the relative match linked list, i.e. the tail.
   *                  May be null.
   * @param head The step that is the current head of the relative
   *                 match step linked list.
   *                 May be null.
   *
   * @return the head of the list.
   *
   * @throws javax.xml.transform.TransformerException
   */
  private static StepPattern createDefaultStepPattern(
          Compiler compiler, int opPos, MatchPatternIterator mpi,
          int analysis, StepPattern tail, StepPattern head)
            throws javax.xml.transform.TransformerException
  {

    int stepType = compiler.getOp(opPos);
    boolean simpleInit = false;
    boolean prevIsOneStepDown = true;

    int whatToShow = compiler.getWhatToShow(opPos);
    StepPattern ai = null;
    int axis, predicateAxis;

    switch (stepType)
    {
    case OpCodes.OP_VARIABLE :
    case OpCodes.OP_EXTFUNCTION :
    case OpCodes.OP_FUNCTION :
    case OpCodes.OP_GROUP :
      prevIsOneStepDown = false;

      Expression expr;

      switch (stepType)
      {
      case OpCodes.OP_VARIABLE :
      case OpCodes.OP_EXTFUNCTION :
      case OpCodes.OP_FUNCTION :
      case OpCodes.OP_GROUP :
        expr = compiler.compileExpression(opPos);
        break;
      default :
        expr = compiler.compileExpression(opPos + 2);
      }

      axis = Axis.FILTEREDLIST;
      predicateAxis = Axis.FILTEREDLIST;
      ai = new FunctionPattern(expr, axis, predicateAxis);
      simpleInit = true;
      break;
    case OpCodes.FROM_ROOT :
      whatToShow = DTMFilter.SHOW_DOCUMENT
                   | DTMFilter.SHOW_DOCUMENT_FRAGMENT;

      axis = Axis.ROOT;
      predicateAxis = Axis.ROOT;
      ai = new StepPattern(DTMFilter.SHOW_DOCUMENT |
                                DTMFilter.SHOW_DOCUMENT_FRAGMENT,
                                axis, predicateAxis);
      break;
    case OpCodes.FROM_ATTRIBUTES :
      whatToShow = DTMFilter.SHOW_ATTRIBUTE;
      axis = Axis.PARENT;
      predicateAxis = Axis.ATTRIBUTE;
      // ai = new StepPattern(whatToShow, Axis.SELF, Axis.SELF);
      break;
    case OpCodes.FROM_NAMESPACE :
      whatToShow = DTMFilter.SHOW_NAMESPACE;
      axis = Axis.PARENT;
      predicateAxis = Axis.NAMESPACE;
      // ai = new StepPattern(whatToShow, axis, predicateAxis);
      break;
    case OpCodes.FROM_ANCESTORS :
      axis = Axis.DESCENDANT;
      predicateAxis = Axis.ANCESTOR;
      break;
    case OpCodes.FROM_CHILDREN :
      axis = Axis.PARENT;
      predicateAxis = Axis.CHILD;
      break;
    case OpCodes.FROM_ANCESTORS_OR_SELF :
      axis = Axis.DESCENDANTORSELF;
      predicateAxis = Axis.ANCESTORORSELF;
      break;
    case OpCodes.FROM_SELF :
      axis = Axis.SELF;
      predicateAxis = Axis.SELF;
      break;
    case OpCodes.FROM_PARENT :
      axis = Axis.CHILD;
      predicateAxis = Axis.PARENT;
      break;
    case OpCodes.FROM_PRECEDING_SIBLINGS :
      axis = Axis.FOLLOWINGSIBLING;
      predicateAxis = Axis.PRECEDINGSIBLING;
      break;
    case OpCodes.FROM_PRECEDING :
      axis = Axis.FOLLOWING;
      predicateAxis = Axis.PRECEDING;
      break;
    case OpCodes.FROM_FOLLOWING_SIBLINGS :
      axis = Axis.PRECEDINGSIBLING;
      predicateAxis = Axis.FOLLOWINGSIBLING;
      break;
    case OpCodes.FROM_FOLLOWING :
      axis = Axis.PRECEDING;
      predicateAxis = Axis.FOLLOWING;
      break;
    case OpCodes.FROM_DESCENDANTS_OR_SELF :
      axis = Axis.ANCESTORORSELF;
      predicateAxis = Axis.DESCENDANTORSELF;
      break;
    case OpCodes.FROM_DESCENDANTS :
      axis = Axis.ANCESTOR;
      predicateAxis = Axis.DESCENDANT;
      break;
    default :
      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
                                 //+ stepType);
    }
    if(null == ai)
    {
      whatToShow = compiler.getWhatToShow(opPos); // %REVIEW%
      ai = new StepPattern(whatToShow, compiler.getStepNS(opPos),
                                compiler.getStepLocalName(opPos),
                                axis, predicateAxis);
    }

    if (false || DEBUG_PATTERN_CREATION)
    {
      System.out.print("new step: "+ ai);
      System.out.print(", axis: " + Axis.getNames(ai.getAxis()));
      System.out.print(", predAxis: " + Axis.getNames(ai.getAxis()));
      System.out.print(", what: ");
      System.out.print("    ");
      ai.debugWhatToShow(ai.getWhatToShow());
    }

    int argLen = compiler.getFirstPredicateOpPos(opPos);

    ai.setPredicates(compiler.getCompiledPredicates(argLen));

    return ai;
  }

  /**
   * Analyze a step and give information about it's predicates.  Right now this
   * just returns true or false if the step has a predicate.
   *
   * @param compiler non-null reference to compiler object that has processed
   *                 the XPath operations into an opcode map.
   * @param opPos The opcode position for the step.
   * @param stepType The type of step, one of OP_GROUP, etc.
   *
   * @return true if step has a predicate.
   *
   * @throws javax.xml.transform.TransformerException
   */
  static boolean analyzePredicate(Compiler compiler, int opPos, int stepType)
          throws javax.xml.transform.TransformerException
  {

    int argLen;

    switch (stepType)
    {
    case OpCodes.OP_VARIABLE :
    case OpCodes.OP_EXTFUNCTION :
    case OpCodes.OP_FUNCTION :
    case OpCodes.OP_GROUP :
      argLen = compiler.getArgLength(opPos);
      break;
    default :
      argLen = compiler.getArgLengthOfStep(opPos);
    }

    int pos = compiler.getFirstPredicateOpPos(opPos);
    int nPredicates = compiler.countPredicates(pos);

    return (nPredicates > 0) ? true : false;
  }

  /**
   * Create the proper Walker from the axes type.
   *
   * @param compiler non-null reference to compiler object that has processed
   *                 the XPath operations into an opcode map.
   * @param opPos The opcode position for the step.
   * @param lpi The owning location path iterator.
   * @param analysis 32 bits of analysis, from which the type of AxesWalker
   *                 may be influenced.
   *
   * @return non-null reference to AxesWalker derivative.
   * @throws RuntimeException if the input is bad.
   */
  private static AxesWalker createDefaultWalker(Compiler compiler, int opPos,
          WalkingIterator lpi, int analysis)
  {

    AxesWalker ai = null;
    int stepType = compiler.getOp(opPos);

    /*
    System.out.println("0: "+compiler.getOp(opPos));
    System.out.println("1: "+compiler.getOp(opPos+1));
    System.out.println("2: "+compiler.getOp(opPos+2));
    System.out.println("3: "+compiler.getOp(opPos+3));
    System.out.println("4: "+compiler.getOp(opPos+4));
    System.out.println("5: "+compiler.getOp(opPos+5));
    */
    boolean simpleInit = false;
    int totalNumberWalkers = (analysis & BITS_COUNT);
    boolean prevIsOneStepDown = true;

    switch (stepType)
    {
    case OpCodes.OP_VARIABLE :
    case OpCodes.OP_EXTFUNCTION :
    case OpCodes.OP_FUNCTION :
    case OpCodes.OP_GROUP :
      prevIsOneStepDown = false;

      if (DEBUG_WALKER_CREATION)
        System.out.println("new walker:  FilterExprWalker: " + analysis
                           + ", " + compiler.toString());

      ai = new FilterExprWalker(lpi);
      simpleInit = true;
      break;
    case OpCodes.FROM_ROOT :
      ai = new AxesWalker(lpi, Axis.ROOT);
      break;
    case OpCodes.FROM_ANCESTORS :
      prevIsOneStepDown = false;
      ai = new ReverseAxesWalker(lpi, Axis.ANCESTOR);
      break;
    case OpCodes.FROM_ANCESTORS_OR_SELF :
      prevIsOneStepDown = false;
      ai = new ReverseAxesWalker(lpi, Axis.ANCESTORORSELF);
      break;
    case OpCodes.FROM_ATTRIBUTES :
      ai = new AxesWalker(lpi, Axis.ATTRIBUTE);
      break;
    case OpCodes.FROM_NAMESPACE :
      ai = new AxesWalker(lpi, Axis.NAMESPACE);
      break;
    case OpCodes.FROM_CHILDREN :
      ai = new AxesWalker(lpi, Axis.CHILD);
      break;
    case OpCodes.FROM_DESCENDANTS :
      prevIsOneStepDown = false;
      ai = new AxesWalker(lpi, Axis.DESCENDANT);
      break;
    case OpCodes.FROM_DESCENDANTS_OR_SELF :
      prevIsOneStepDown = false;
      ai = new AxesWalker(lpi, Axis.DESCENDANTORSELF);
      break;
    case OpCodes.FROM_FOLLOWING :
      prevIsOneStepDown = false;
      ai = new AxesWalker(lpi, Axis.FOLLOWING);
      break;
    case OpCodes.FROM_FOLLOWING_SIBLINGS :
      prevIsOneStepDown = false;
      ai = new AxesWalker(lpi, Axis.FOLLOWINGSIBLING);
      break;
    case OpCodes.FROM_PRECEDING :
      prevIsOneStepDown = false;
      ai = new ReverseAxesWalker(lpi, Axis.PRECEDING);
      break;
    case OpCodes.FROM_PRECEDING_SIBLINGS :
      prevIsOneStepDown = false;
      ai = new ReverseAxesWalker(lpi, Axis.PRECEDINGSIBLING);
      break;
    case OpCodes.FROM_PARENT :
      prevIsOneStepDown = false;
      ai = new ReverseAxesWalker(lpi, Axis.PARENT);
      break;
    case OpCodes.FROM_SELF :
      ai = new AxesWalker(lpi, Axis.SELF);
      break;
    default :
      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
                                 //+ stepType);
    }

    if (simpleInit)
    {
      ai.initNodeTest(DTMFilter.SHOW_ALL);
    }
    else
    {
      int whatToShow = compiler.getWhatToShow(opPos);

      /*
      System.out.print("construct: ");
      NodeTest.debugWhatToShow(whatToShow);
      System.out.println("or stuff: "+(whatToShow & (DTMFilter.SHOW_ATTRIBUTE
                             | DTMFilter.SHOW_ELEMENT
                             | DTMFilter.SHOW_PROCESSING_INSTRUCTION)));
      */
      if ((0 == (whatToShow
                 & (DTMFilter.SHOW_ATTRIBUTE | DTMFilter.SHOW_NAMESPACE | DTMFilter.SHOW_ELEMENT
                    | DTMFilter.SHOW_PROCESSING_INSTRUCTION))) || (whatToShow == DTMFilter.SHOW_ALL))
        ai.initNodeTest(whatToShow);
      else
      {
        ai.initNodeTest(whatToShow, compiler.getStepNS(opPos),
                        compiler.getStepLocalName(opPos));
      }
    }

    return ai;
  }

  public static String getAnalysisString(int analysis)
  {
    StringBuffer buf = new StringBuffer();
    buf.append("count: ").append(getStepCount(analysis)).append(' ');
    if((analysis & BIT_NODETEST_ANY) != 0)
    {
      buf.append("NTANY|");
    }
    if((analysis & BIT_PREDICATE) != 0)
    {
      buf.append("PRED|");
    }
    if((analysis & BIT_ANCESTOR) != 0)
    {
      buf.append("ANC|");
    }
    if((analysis & BIT_ANCESTOR_OR_SELF) != 0)
    {
      buf.append("ANCOS|");
    }
    if((analysis & BIT_ATTRIBUTE) != 0)
    {
      buf.append("ATTR|");
    }
    if((analysis & BIT_CHILD) != 0)
    {
      buf.append("CH|");
    }
    if((analysis & BIT_DESCENDANT) != 0)
    {
      buf.append("DESC|");
    }
    if((analysis & BIT_DESCENDANT_OR_SELF) != 0)
    {
      buf.append("DESCOS|");
    }
    if((analysis & BIT_FOLLOWING) != 0)
    {
      buf.append("FOL|");
    }
    if((analysis & BIT_FOLLOWING_SIBLING) != 0)
    {
      buf.append("FOLS|");
    }
    if((analysis & BIT_NAMESPACE) != 0)
    {
      buf.append("NS|");
    }
    if((analysis & BIT_PARENT) != 0)
    {
      buf.append("P|");
    }
    if((analysis & BIT_PRECEDING) != 0)
    {
      buf.append("PREC|");
    }
    if((analysis & BIT_PRECEDING_SIBLING) != 0)
    {
      buf.append("PRECS|");
    }
    if((analysis & BIT_SELF) != 0)
    {
      buf.append(".|");
    }
    if((analysis & BIT_FILTER) != 0)
    {
      buf.append("FLT|");
    }
    if((analysis & BIT_ROOT) != 0)
    {
      buf.append("R|");
    }
    return buf.toString();
  }

  /** Set to true for diagnostics about walker creation */
  static final boolean DEBUG_PATTERN_CREATION = false;

  /** Set to true for diagnostics about walker creation */
  static final boolean DEBUG_WALKER_CREATION = false;

  /** Set to true for diagnostics about iterator creation */
  static final boolean DEBUG_ITERATOR_CREATION = false;

  public static boolean hasPredicate(int analysis)
  {
    return (0 != (analysis & BIT_PREDICATE));
  }

  public static boolean isWild(int analysis)
  {
    return (0 != (analysis & BIT_NODETEST_ANY));
  }

  public static boolean walksAncestors(int analysis)
  {
    return isSet(analysis, BIT_ANCESTOR | BIT_ANCESTOR_OR_SELF);
  }

  public static boolean walksAttributes(int analysis)
  {
    return (0 != (analysis & BIT_ATTRIBUTE));
  }

  public static boolean walksNamespaces(int analysis)
  {
    return (0 != (analysis & BIT_NAMESPACE));
  }

  public static boolean walksChildren(int analysis)
  {
    return (0 != (analysis & BIT_CHILD));
  }

  public static boolean walksDescendants(int analysis)
  {
    return isSet(analysis, BIT_DESCENDANT | BIT_DESCENDANT_OR_SELF);
  }

  public static boolean walksSubtree(int analysis)
  {
    return isSet(analysis, BIT_DESCENDANT | BIT_DESCENDANT_OR_SELF | BIT_CHILD);
  }

  public static boolean walksSubtreeOnlyMaybeAbsolute(int analysis)
  {
    return walksSubtree(analysis)
           && !walksExtraNodes(analysis)
           && !walksUp(analysis)
           && !walksSideways(analysis)
           ;
  }

  public static boolean walksSubtreeOnly(int analysis)
  {
    return walksSubtreeOnlyMaybeAbsolute(analysis)
           && !isAbsolute(analysis)
           ;
  }

  public static boolean walksFilteredList(int analysis)
  {
    return isSet(analysis, BIT_FILTER);
  }

  public static boolean walksSubtreeOnlyFromRootOrContext(int analysis)
  {
    return walksSubtree(analysis)
           && !walksExtraNodes(analysis)
           && !walksUp(analysis)
           && !walksSideways(analysis)
           && !isSet(analysis, BIT_FILTER)
           ;
  }

  public static boolean walksInDocOrder(int analysis)
  {
    return (walksSubtreeOnlyMaybeAbsolute(analysis)
           || walksExtraNodesOnly(analysis)
           || walksFollowingOnlyMaybeAbsolute(analysis))
           && !isSet(analysis, BIT_FILTER)
           ;
  }

  public static boolean walksFollowingOnlyMaybeAbsolute(int analysis)
  {
    return isSet(analysis, BIT_SELF | BIT_FOLLOWING_SIBLING | BIT_FOLLOWING)
           && !walksSubtree(analysis)
           && !walksUp(analysis)
           && !walksSideways(analysis)
           ;
  }

  public static boolean walksUp(int analysis)
  {
    return isSet(analysis, BIT_PARENT | BIT_ANCESTOR | BIT_ANCESTOR_OR_SELF);
  }

  public static boolean walksSideways(int analysis)
  {
    return isSet(analysis, BIT_FOLLOWING | BIT_FOLLOWING_SIBLING |
                           BIT_PRECEDING | BIT_PRECEDING_SIBLING);
  }

  public static boolean walksExtraNodes(int analysis)
  {
    return isSet(analysis, BIT_NAMESPACE | BIT_ATTRIBUTE);
  }

  public static boolean walksExtraNodesOnly(int analysis)
  {
    return walksExtraNodes(analysis)
           && !isSet(analysis, BIT_SELF)
           && !walksSubtree(analysis)
           && !walksUp(analysis)
           && !walksSideways(analysis)
           && !isAbsolute(analysis)
           ;
  }

  public static boolean isAbsolute(int analysis)
  {
    return isSet(analysis, BIT_ROOT | BIT_FILTER);
  }

  public static boolean walksChildrenOnly(int analysis)
  {
    return walksChildren(analysis)
           && !isSet(analysis, BIT_SELF)
           && !walksExtraNodes(analysis)
           && !walksDescendants(analysis)
           && !walksUp(analysis)
           && !walksSideways(analysis)
           && (!isAbsolute(analysis) || isSet(analysis, BIT_ROOT))
           ;
  }

  public static boolean walksChildrenAndExtraAndSelfOnly(int analysis)
  {
    return walksChildren(analysis)
           && !walksDescendants(analysis)
           && !walksUp(analysis)
           && !walksSideways(analysis)
           && (!isAbsolute(analysis) || isSet(analysis, BIT_ROOT))
           ;
  }

  public static boolean walksDescendantsAndExtraAndSelfOnly(int analysis)
  {
    return !walksChildren(analysis)
           && walksDescendants(analysis)
           && !walksUp(analysis)
           && !walksSideways(analysis)
           && (!isAbsolute(analysis) || isSet(analysis, BIT_ROOT))
           ;
  }

  public static boolean walksSelfOnly(int analysis)
  {
    return isSet(analysis, BIT_SELF)
           && !walksSubtree(analysis)
           && !walksUp(analysis)
           && !walksSideways(analysis)
           && !isAbsolute(analysis)
           ;
  }


  public static boolean walksUpOnly(int analysis)
  {
    return !walksSubtree(analysis)
           && walksUp(analysis)
           && !walksSideways(analysis)
           && !isAbsolute(analysis)
           ;
  }

  public static boolean walksDownOnly(int analysis)
  {
    return walksSubtree(analysis)
           && !walksUp(analysis)
           && !walksSideways(analysis)
           && !isAbsolute(analysis)
           ;
  }

  public static boolean walksDownExtraOnly(int analysis)
  {
    return walksSubtree(analysis) &&  walksExtraNodes(analysis)
           && !walksUp(analysis)
           && !walksSideways(analysis)
           && !isAbsolute(analysis)
           ;
  }

  public static boolean canSkipSubtrees(int analysis)
  {
    return isSet(analysis, BIT_CHILD) | walksSideways(analysis);
  }

  public static boolean canCrissCross(int analysis)
  {
    // This could be done faster.  Coded for clarity.
    if(walksSelfOnly(analysis))
      return false;
    else if(walksDownOnly(analysis) && !canSkipSubtrees(analysis))
      return false;
    else if(walksChildrenAndExtraAndSelfOnly(analysis))
      return false;
    else if(walksDescendantsAndExtraAndSelfOnly(analysis))
      return false;
    else if(walksUpOnly(analysis))
      return false;
    else if(walksExtraNodesOnly(analysis))
      return false;
    else if(walksSubtree(analysis)
           && (walksSideways(analysis)
            || walksUp(analysis)
            || canSkipSubtrees(analysis)))
      return true;
    else
      return false;
  }

  /**
   * Tell if the pattern can be 'walked' with the iteration steps in natural
   * document order, without duplicates.
   *
   * @param analysis The general analysis of the pattern.
   *
   * @return true if the walk can be done in natural order.
   *
   * @throws javax.xml.transform.TransformerException
   */
  static public boolean isNaturalDocOrder(int analysis)
  {
    if(canCrissCross(analysis) || isSet(analysis, BIT_NAMESPACE) ||
       walksFilteredList(analysis))
      return false;

    if(walksInDocOrder(analysis))
      return true;

    return false;
  }

  /**
   * Tell if the pattern can be 'walked' with the iteration steps in natural
   * document order, without duplicates.
   *
   * @param compiler non-null reference to compiler object that has processed
   *                 the XPath operations into an opcode map.
   * @param stepOpCodePos The opcode position for the step.
   * @param stepIndex The top-level step index withing the iterator.
   * @param analysis The general analysis of the pattern.
   *
   * @return true if the walk can be done in natural order.
   *
   * @throws javax.xml.transform.TransformerException
   */
  private static boolean isNaturalDocOrder(
          Compiler compiler, int stepOpCodePos, int stepIndex, int analysis)
            throws javax.xml.transform.TransformerException
  {
    if(canCrissCross(analysis))
      return false;

    // Namespaces can present some problems, so just punt if we're looking for
    // these.
    if(isSet(analysis, BIT_NAMESPACE))
      return false;

    // The following, preceding, following-sibling, and preceding sibling can
    // be found in doc order if we get to this point, but if they occur
    // together, they produce
    // duplicates, so it's better for us to eliminate this case so we don't
    // have to check for duplicates during runtime if we're using a
    // WalkingIterator.
    if(isSet(analysis, BIT_FOLLOWING | BIT_FOLLOWING_SIBLING) &&
       isSet(analysis, BIT_PRECEDING | BIT_PRECEDING_SIBLING))
      return  false;

    // OK, now we have to check for select="@*/axis::*" patterns, which
    // can also cause duplicates to happen.  But select="axis*/@::*" patterns
    // are OK, as are select="@foo/axis::*" patterns.
    // Unfortunately, we can't do this just via the analysis bits.

    int stepType;
    int stepCount = 0;
    boolean foundWildAttribute = false;

    // Steps that can traverse anything other than down a
    // subtree or that can produce duplicates when used in
    // combonation are counted with this variable.
    int potentialDuplicateMakingStepCount = 0;

    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
    {
      stepCount++;

      switch (stepType)
      {
      case OpCodes.FROM_ATTRIBUTES :
      case OpCodes.MATCH_ATTRIBUTE :
        if(foundWildAttribute) // Maybe not needed, but be safe.
          return false;

        // This doesn't seem to work as a test for wild card.  Hmph.
        // int nodeTestType = compiler.getStepTestType(stepOpCodePos);

        String localName = compiler.getStepLocalName(stepOpCodePos);
        // System.err.println("localName: "+localName);
        if(localName.equals("*"))
        {
          foundWildAttribute = true;
        }
        break;
      case OpCodes.FROM_FOLLOWING :
      case OpCodes.FROM_FOLLOWING_SIBLINGS :
      case OpCodes.FROM_PRECEDING :
      case OpCodes.FROM_PRECEDING_SIBLINGS :
      case OpCodes.FROM_PARENT :
      case OpCodes.OP_VARIABLE :
      case OpCodes.OP_EXTFUNCTION :
      case OpCodes.OP_FUNCTION :
      case OpCodes.OP_GROUP :
      case OpCodes.FROM_NAMESPACE :
      case OpCodes.FROM_ANCESTORS :
      case OpCodes.FROM_ANCESTORS_OR_SELF :
      case OpCodes.MATCH_ANY_ANCESTOR :
      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
      case OpCodes.FROM_DESCENDANTS_OR_SELF :
      case OpCodes.FROM_DESCENDANTS :
        if(potentialDuplicateMakingStepCount > 0)
            return false;
        potentialDuplicateMakingStepCount++;
      case OpCodes.FROM_ROOT :
      case OpCodes.FROM_CHILDREN :
      case OpCodes.FROM_SELF :
        if(foundWildAttribute)
          return false;
        break;
      default :
        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
                                  // + stepType);
      }

      int nextStepOpCodePos = compiler.getNextStepPos(stepOpCodePos);

      if (nextStepOpCodePos < 0)
        break;

      stepOpCodePos = nextStepOpCodePos;
    }

    return true;
  }

  public static boolean isOneStep(int analysis)
  {
    return (analysis & BITS_COUNT) == 0x00000001;
  }

  public static int getStepCount(int analysis)
  {
    return (analysis & BITS_COUNT);
  }

  /**
   * First 8 bits are the number of top-level location steps.  Hopefully
   *  there will never be more that 255 location steps!!!
   */
  public static final int BITS_COUNT = 0x000000FF;

  /** 4 bits are reserved for future use. */
  public static final int BITS_RESERVED = 0x00000F00;

  /** Bit is on if the expression contains a top-level predicate. */
  public static final int BIT_PREDICATE = (0x00001000);

  /** Bit is on if any of the walkers contain an ancestor step. */
  public static final int BIT_ANCESTOR = (0x00001000 << 1);

  /** Bit is on if any of the walkers contain an ancestor-or-self step. */
  public static final int BIT_ANCESTOR_OR_SELF = (0x00001000 << 2);

  /** Bit is on if any of the walkers contain an attribute step. */
  public static final int BIT_ATTRIBUTE = (0x00001000 << 3);

  /** Bit is on if any of the walkers contain a child step. */
  public static final int BIT_CHILD = (0x00001000 << 4);

  /** Bit is on if any of the walkers contain a descendant step. */
  public static final int BIT_DESCENDANT = (0x00001000 << 5);

  /** Bit is on if any of the walkers contain a descendant-or-self step. */
  public static final int BIT_DESCENDANT_OR_SELF = (0x00001000 << 6);

  /** Bit is on if any of the walkers contain a following step. */
  public static final int BIT_FOLLOWING = (0x00001000 << 7);

  /** Bit is on if any of the walkers contain a following-sibiling step. */
  public static final int BIT_FOLLOWING_SIBLING = (0x00001000 << 8);

  /** Bit is on if any of the walkers contain a namespace step. */
  public static final int BIT_NAMESPACE = (0x00001000 << 9);

  /** Bit is on if any of the walkers contain a parent step. */
  public static final int BIT_PARENT = (0x00001000 << 10);

  /** Bit is on if any of the walkers contain a preceding step. */
  public static final int BIT_PRECEDING = (0x00001000 << 11);

  /** Bit is on if any of the walkers contain a preceding-sibling step. */
  public static final int BIT_PRECEDING_SIBLING = (0x00001000 << 12);

  /** Bit is on if any of the walkers contain a self step. */
  public static final int BIT_SELF = (0x00001000 << 13);

  /**
   * Bit is on if any of the walkers contain a filter (i.e. id(), extension
   *  function, etc.) step.
   */
  public static final int BIT_FILTER = (0x00001000 << 14);

  /** Bit is on if any of the walkers contain a root step. */
  public static final int BIT_ROOT = (0x00001000 << 15);

  /**
   * If any of these bits are on, the expression may likely traverse outside
   *  the given subtree.
   */
  public static final int BITMASK_TRAVERSES_OUTSIDE_SUBTREE = (BIT_NAMESPACE  // ??
                                                                | BIT_PRECEDING_SIBLING
                                                                | BIT_PRECEDING
                                                                | BIT_FOLLOWING_SIBLING
                                                                | BIT_FOLLOWING
                                                                | BIT_PARENT  // except parent of attrs.
                                                                | BIT_ANCESTOR_OR_SELF
                                                                | BIT_ANCESTOR
                                                                | BIT_FILTER
                                                                | BIT_ROOT);

  /**
   * Bit is on if any of the walkers can go backwards in document
   *  order from the context node.
   */
  public static final int BIT_BACKWARDS_SELF = (0x00001000 << 16);

  /** Found "//foo" pattern */
  public static final int BIT_ANY_DESCENDANT_FROM_ROOT = (0x00001000 << 17);

  /**
   * Bit is on if any of the walkers contain an node() test.  This is
   *  really only useful if the count is 1.
   */
  public static final int BIT_NODETEST_ANY = (0x00001000 << 18);

  // can't go higher than 18!

  /** Bit is on if the expression is a match pattern. */
  public static final int BIT_MATCH_PATTERN = (0x00001000 << 19);
}
