protected PatternExpr copy() {
   List<PatternExpr> newPatterns = new ArrayList<PatternExpr>(patterns.size());
   for (PatternExpr p : patterns) {
     newPatterns.add(p.copy());
   }
   return new AndPatternExpr(newPatterns);
 }
 protected PatternExpr getSequencePatternExpr(String name, boolean copy) {
   Object obj = variables.get(name);
   if (obj != null) {
     if (obj instanceof PatternExpr) {
       PatternExpr pe = (PatternExpr) obj;
       return (copy) ? pe.copy() : pe;
     } else if (obj instanceof NodePattern) {
       return new NodePatternExpr((NodePattern) obj);
     } else if (obj instanceof String) {
       try {
         return parser.parseSequence(this, (String) obj);
       } catch (Exception pex) {
         throw new RuntimeException("Error parsing " + obj + " to sequence pattern", pex);
       }
     } else {
       throw new Error("Invalid sequence pattern variable class: " + obj.getClass());
     }
   }
   return null;
 }
 protected PatternExpr copy() {
   return new RepeatPatternExpr(pattern.copy(), minMatch, maxMatch, greedyMatch);
 }
 protected PatternExpr copy() {
   return new GroupPatternExpr(pattern.copy(), capture);
 }