/**
  * Private constructor used after parsing is done.
  *
  * @param originalKey for reference
  * @param upLevel How far up the tree to go
  * @param subPath Where to go down the tree
  */
 private TransposePathElement(String originalKey, int upLevel, String subPath) {
   super(originalKey);
   this.upLevel = upLevel;
   if (StringTools.isEmpty(subPath)) {
     this.subPathReader = null;
     canonicalForm = "@(" + upLevel + ",)";
   } else {
     subPathReader = new TransposeReader(subPath);
     canonicalForm = "@(" + upLevel + "," + subPathReader.getCanonicalForm() + ")";
   }
 }
  /**
   * This method is used when the TransposePathElement is used on the LFH as data.
   *
   * <p>Aka, normal "evaluate" returns either a Number or a String.
   *
   * @param walkedPath WalkedPath to evaluate against
   * @return The data specified by this TransposePathElement.
   */
  public Optional<Object> objectEvaluate(WalkedPath walkedPath) {
    // Grap the data we need from however far up the tree we are supposed to go
    PathStep pathStep = walkedPath.elementFromEnd(upLevel);

    if (pathStep == null) {
      return Optional.empty();
    }

    Object treeRef = pathStep.getTreeRef();

    // Now walk down from that level using the subPathReader
    if (subPathReader == null) {
      return Optional.of(treeRef);
    } else {
      return subPathReader.read(treeRef, walkedPath);
    }
  }