code: public int compareTo(Path o) {
  
          // Sanity check.
          if (o == null) {
              throw new NullPointerException();
          }
  
          // If these are not the same type, do the simple comparison.
          if (this.type != o.type) {
              return type.compareTo(o.type);
          }
  
          // Same type of path, so check first the number of terms. If not equal,
          // then it is easy to decide the order. (Longer paths come before
          // shorter ones.)
          int mySize = this.terms.length;
          int otherSize = o.terms.length;
          if (mySize != otherSize) {
              return (mySize < otherSize) ? 1 : -1;
          }
  
          // Ok, the hard case, the two paths are of the same type and have the
          // same number of terms.
          for (int i = 0; i < mySize; i++) {
              Term myTerm = this.terms[i];
              Term otherTerm = o.terms[i];
              int comparison = myTerm.compareTo(otherTerm);
              if (comparison != 0) {
                  return comparison;
              }
          }
  
          // We've gone through all of the checks, so the two paths must be equal;
          // return zero.
          return 0;
      }
docs: The default ordering for paths is such that it will produce a
  post-traversal ordering. All relative paths will be before absolute paths
  which are before external paths.