public MatchPath getTailPath(int from) {
    if (from > lastIndex || from < 0) throw new IllegalArgumentException();

    AttributeMatchPath copy = pool.getAttributeMatchPath();
    for (int i = from; i <= lastIndex; i++) {
      copy.add(list[i]);
    }
    return copy;
  }
  public AttributeMatchPath getHeadPath(int to) {
    if (to > lastIndex || to < 0) throw new IllegalArgumentException();

    AttributeMatchPath copy = pool.getAttributeMatchPath();
    copy.addAttribute(match);
    for (int i = 1; i <= to; i++) {
      copy.add(list[i]);
    }
    return copy;
  }
 public MatchPath getTailPath(SRule from) {
   boolean containsFrom = false;
   AttributeMatchPath copy = pool.getAttributeMatchPath();
   for (int i = 0; i <= lastIndex; i++) {
     if (list[i] == from) {
       containsFrom = true;
     }
     if (containsFrom) {
       copy.add(list[i]);
     }
   }
   if (!containsFrom) throw new IllegalArgumentException();
   return copy;
 }
 public AttributeMatchPath getHeadPath(SRule to) {
   boolean containsFrom = false;
   AttributeMatchPath copy = pool.getAttributeMatchPath();
   copy.addAttribute(match);
   for (int i = 1; i <= lastIndex; i++) {
     copy.add(list[i]);
     if (list[i] == to) {
       containsFrom = true;
       break;
     }
   }
   if (!containsFrom) throw new IllegalArgumentException();
   return copy;
 }