}
  List filterCandidates(List candidates, boolean cascade)  {    int len = candidates.size();    int tlen = tests.length;    if (tlen > 0 && len > 0)      {        // Present the result of each successful generation to the next test        for (int j = 0; j < tlen && len > 0; j++)          {            Test test = tests[j];            List successful = new ArrayList(len);            for (int i = 0; i < len; i++)              {                Node node = (Node) candidates.get(i);                if (cascade)                  {                    // Documents and DocumentFragments should be considered                    // if part of a location path where the axis involves                    // the SELF concept                    short nodeType = node.getNodeType();                    if ((nodeType == Node.DOCUMENT_NODE ||                         nodeType == Node.DOCUMENT_FRAGMENT_NODE) &&                        (axis == DESCENDANT_OR_SELF ||                         axis == ANCESTOR_OR_SELF ||                         axis == SELF) &&                        (tests.length == 1 &&                         tests[0] instanceof NodeTypeTest &&                         ((NodeTypeTest) tests[0]).type == (short) 0))                      {                        successful.add(node);                        continue;                      }                  }                if (test.matches(node, i + 1, len))                  {                    successful.add(node);                  }                /*                   System.err.println("Testing "+node);                   int p = getContextPosition(node);                   int l = getContextSize(node);                   if (test.matches(node, p, l))                   {                   successful.add(node);                   }*/              }            candidates = successful;            len = candidates.size();          }      }    return candidates;  }