/* ==========================================================================
Compares to subtrees, using the tree depth as tie breaker when
the subtrees have equal frequency. This minimizes the worst case length.
329557
function SMALLER(tree, n, m) {
		return tree[n].fc < tree[m].fc || (tree[n].fc === tree[m].fc && depth[n] <= depth[m]);
	}
805993
private void divide(int[] idx, double[] data, ArrayList<int[]> ret, int start, int end, int depth) {
    if(depth == 0) {
      int[] a = Arrays.copyOfRange(idx, start, end);
      Arrays.sort(a);
      ret.add(a);
      return;
    }
    final int count = end - start;
    if(count == 0) {
      // Corner case, that should barely happen. But for ties, we currently
      // Do not yet assure that it doesn't happen!
      for(int j = 1 << depth; j > 0; --j) {
        ret.add(new int[0]);
      }
      return;
    }
    double m = 0.;
    for(int i = start; i < end; i++) {
      m += data[i];
    }
    m /= count;
    int pos = Arrays.binarySearch(data, start, end, m);
    if(pos >= 0) {
      // Ties: try to choose the most central element.
      final int opt = (start + end) >> 1;
      while(data[pos] == m) {
        if(pos < opt) {
          pos++;
        }
        else if(pos > opt) {
          pos--;
        }
        else {
          break;
        }
      }
    }
    else {
      pos = (-pos - 1);
    }
    divide(idx, data, ret, start, pos, depth - 1);
    divide(idx, data, ret, pos, end, depth - 1);
  }
609852
function bfsOrder(root) {
    var inqueue = [root], outqueue = [];
    root._bfs_parent = null;
    while (inqueue.length > 0) {
      var elem = inqueue.shift();
      outqueue.push(elem);
      var children = elem.childNodes;
      var liParent = null;
      for (var i=0 ; i<children.length; i++) {
        if (children[i].nodeType == 1) {// element node
          if (children[i].tagName === 'LI') {
            liParent = children[i];
          } else if ((children[i].tagName === 'UL' || children[i].tagName === 'OL') && liParent) {
            liParent.appendChild(children[i]);
            i--;
            continue;
          } 
          children[i]._bfs_parent = elem;
          inqueue.push(children[i]);
        }
      }
    }
    outqueue.shift();
    return outqueue;
  }
787440
public static boolean deepEquals(Object a, Object b) {
        if (a == null || b == null) {
            return a == b;
        } else if (a instanceof Object[] && b instanceof Object[]) {
            return Arrays.deepEquals((Object[]) a, (Object[]) b);
        } else if (a instanceof boolean[] && b instanceof boolean[]) {
            return Arrays.equals((boolean[]) a, (boolean[]) b);
        } else if (a instanceof byte[] && b instanceof byte[]) {
            return Arrays.equals((byte[]) a, (byte[]) b);
        } else if (a instanceof char[] && b instanceof char[]) {
            return Arrays.equals((char[]) a, (char[]) b);
        } else if (a instanceof double[] && b instanceof double[]) {
            return Arrays.equals((double[]) a, (double[]) b);
        } else if (a instanceof float[] && b instanceof float[]) {
            return Arrays.equals((float[]) a, (float[]) b);
        } else if (a instanceof int[] && b instanceof int[]) {
            return Arrays.equals((int[]) a, (int[]) b);
        } else if (a instanceof long[] && b instanceof long[]) {
            return Arrays.equals((long[]) a, (long[]) b);
        } else if (a instanceof short[] && b instanceof short[]) {
            return Arrays.equals((short[]) a, (short[]) b);
        }
        return a.equals(b);
    }

    /**
     * NULL safe reference unwrap
     */
    public static <T> T unwrap(Reference<T> reference) {
        return reference == null ? null : reference.get();
    }

    /**
     * NULL safe reference unwrap
     */
    public static <T> T unwrap(AtomicReference<T> reference) {
        return reference == null ? null : reference.get();
    }

    public static boolean isNull(Object object) {
        return object == null;
    }

    public static boolean nonNull(Object object) {
        return object != null;
    }

    /**
     * Null-safe equivalent of {@code a.equals(b)}.
     */
    public static boolean equal(Object a, Object b) {
        return (a == null) ? (b == null) : a.equals(b);
    }

    /**
     * Null-safe equivalent of {@code !a.equals(b)}.
     */
    public static boolean notEqual(Object a, Object b) {
        return !equal(a, b);
    }

    /**
     * Convenience wrapper for {@link Arrays#hashCode}, adding varargs.
     * This can be used to compute a hash code for an object's fields as follows:
     * {@code Objects.hash(a, b, c)}.
     */
    public static int hash(Object... values) {
        return Arrays.hashCode(values);
    }

    /**
     * Convenience wrapper for {@link Arrays#hashCode}, adding varargs.
     * This can be used to compute a hash code for an object's fields as follows:
     * {@code Objects.hash(a, b, c)}.
     */
    public static int hash(List<?> values) {
        if (values == null)
            return 0;

        int result = 1;

        for (Object element : values)
            result = 31 * result + (element == null ? 0 : element.hashCode());

        return result;
    }

    /**
     * Convenience wrapper for {@link Arrays#hashCode}, adding varargs.
     * This can be used to compute a hash code for an object's fields as follows:
     * {@code Objects.hash(a, b, c)}.
     */
    public static int absHash(Object... values) {
        return abs(Arrays.hashCode(values));
    }

    /**
     * Returns 0 for null or {@code o.hashCode()}.
     */
    public static int hashCode(Object o) {
        return (o == null) ? 0 : o.hashCode();
    }

    /**
     * @return secondary hash from object's hash
     */
    public static int secondaryHash(Object key) {
        return secondaryHash(key.hashCode());
    }

    /**
     * @return secondary hash from identity hash
     */
    public static int secondaryIdentityHash(Object key) {
        return secondaryHash(System.identityHashCode(key));
    }

    /**
     * @return secondary hash from hash
     */
    private static int secondaryHash(int h) {
        // Spread bits to regularize both segment and index locations,
        // using variant of single-word Wang/Jenkins hash.
        h += (h << 15) ^ 0xffffcd7d;
        h ^= (h >>> 10);
        h += (h << 3);
        h ^= (h >>> 6);
        h += (h << 2) + (h << 14);
        return h ^ (h >>> 16);
    }

    /**
     * Returns {@code o} if non-null, or throws {@code NullPointerException}.
     */
    public static <T> T requireNonNull(T o) {
        if (o == null) {
            throw new NullPointerException();
        }
        return o;
    }

    /**
     * Returns {@code o} if non-null, or throws {@code NullPointerException}
     * with the given detail message.
     */
    public static <T> T requireNonNull(T o, String message) {
        if (o == null) {
            throw new NullPointerException(message);
        }
        return o;
    }

    /**
     * Returns true if the string is null or 0-length.
     *
     * @param str the string to be examined
     * @return true if str is null or zero length
     */
    public static boolean isEmpty(CharSequence str) {
        if (str == null || str.length() == 0)
            return true;
        else
            return false;
    }

    /**
     * Returns false if the string is null or 0-length.
     *
     * @param str the string to be examined
     * @return false if str is null or zero length
     */
    public static boolean isNotEmpty(CharSequence str) {
        if (str == null || str.length() == 0)
            return false;
        else
            return true;
    }

    /**
     * Returns NULL for null or {@code o.toString()}.
     */
    public static String toString(Object o) {
        return (o == null) ? null : o.toString();
    }

    /**
     * Returns NULL for null or {@code o.toString()}.
     */
    public static List<String> toString(Object... o) {
        List<String> strings = new ArrayList<>();
        for (Object item : o) {
            strings.add(toString(item));
        }
        return strings;
    }

    /**
     * Returns NULL for null or {@code o.toString()}.
     */
    public static List<String> toString(Collection o) {
        List<String> strings = new ArrayList<>();
        for (Object item : o) {
            strings.add(toString(item));
        }
        return strings;
    }

    /**
     * Returns "null" for null or {@code o.toString()}.
     */
    public static String string(Object o) {
        return (o == null) ? "null" : o.toString();
    }

    /**
     * Returns "null" for null or {@code o.toString()}.
     */
    public static List<String> string(Object... o) {
        List<String> strings = new ArrayList<>();
        for (Object item : o) {
            strings.add(string(item));
        }
        return strings;
    }

    /**
     * Returns "null" for null or {@code o.toString()}.
     */
    public static List<String> string(Collection o) {
        List<String> strings = new ArrayList<>();
        for (Object item : o) {
            strings.add(toString(item));
        }
        return strings;
    }

    /**
     * Returns {@code nullString} for null or {@code o.toString()}.
     */
    public static String string(Object o, String nullString) {
        return (o == null) ? nullString : o.toString();
    }

    /**
     * NULL safe startsWith()
     */
    public static boolean startsWith(String string, String prefix) {
        return isEmpty(string) && isEmpty(prefix) || string != null && string.startsWith(prefix);
    }

    /**
     * NULL safe contains()
     */
    public static boolean contains(String string, String value) {
        return safe(string).contains(value);
    }

    /**
     * NULL safe replace()
     */
    public static String replace(String string, CharSequence target, CharSequence replacement) {
        return string == null ? null : string.replace(target, replacement);
    }

    /**
     * NULL safe replaceFirst()
     */
    public static String replaceFirst(String string, String regex, String replacement) {
        return string == null ? null : string.replaceFirst(regex, replacement);
    }

    /**
     * NULL safe replaceAll()
     */
    public static String replaceAll(String string, String regex, String replacement) {
        return string == null ? null : string.replaceAll(regex, replacement);
    }

    /**
     * NULL safe trim()
     */
    public static String trim(String string) {
        return string == null ? null : string.trim();
    }

    /**
     * NULL safe trim()
     */
    public static boolean isTrimmedEmpty(String string) {
        return string == null || string.trim().isEmpty();
    }

    /**
     * Returns a string containing the tokens joined.
     *
     * @param delimiter object to insert between {@code tokens}
     * @param tokens    an array objects to be joined
     */
    public static <T> List<T> insertBetween(T delimiter, List<T> tokens) {
        List<T> sb = new ArrayList<>();
        boolean firstTime = true;
        for (T token : tokens) {
            if (firstTime) {
                firstTime = false;
            } else {
                sb.add(delimiter);
            }
            sb.add(token);
        }
        return sb;
    }

    /**
     * Returns a string containing the tokens joined.
     *
     * @param list an array objects to be joined. Strings will be formed from
     *             the objects by calling object.toString().
     */
    public static CharSequence join(Object... list) {
        return join("", list);
    }

    /**
     * Returns a string containing the tokens joined by delimiters.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString().
     */
    public static String join(CharSequence delimiter, Object... tokens) {
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token : tokens) {
            if (firstTime) {
                firstTime = false;
            } else {
                sb.append(delimiter);
            }
            sb.append(token);
        }
        return sb.toString();
    }

    /**
     * Returns a string containing the tokens joined by delimiters.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString() NULL items won't be added.
     */
    public static String joinNotNull(CharSequence delimiter, Object... tokens) {
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token : tokens) {
            if (token != null) {
                if (firstTime) {
                    firstTime = false;
                } else {
                    sb.append(delimiter);
                }
                sb.append(token);
            }
        }
        return sb.toString();
    }

    /**
     * Returns a string containing the tokens joined by delimiters.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString() EMPTY items won't be added.
     */
    public static String joinNotEmpty(CharSequence delimiter, Object... tokens) {
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token : tokens) {
            if (!isEmpty(toString(token))) {
                if (firstTime) {
                    firstTime = false;
                } else {
                    sb.append(delimiter);
                }
                sb.append(token);
            }
        }
        return sb.toString();
    }


    /**
     * Returns a string containing the tokens joined.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString().
     */
    public static CharSequence join(Iterable tokens) {
        return join("", tokens);
    }

    /**
     * Returns a string containing the tokens joined by delimiters.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString().
     */
    public static String join(CharSequence delimiter, Iterable tokens) {
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token : tokens) {
            if (firstTime) {
                firstTime = false;
            } else {
                sb.append(delimiter);
            }
            sb.append(token);
        }
        return sb.toString();
    }

    /**
     * Returns a string containing the tokens joined by delimiters.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString() NULL items won't be added.
     */
    public static String joinNotNull(CharSequence delimiter, Iterable tokens) {
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token : tokens) {
            if (token != null) {
                if (firstTime) {
                    firstTime = false;
                } else {
                    sb.append(delimiter);
                }
                sb.append(token);
            }
        }
        return sb.toString();
    }

    /**
     * Returns a string containing the tokens joined by delimiters.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString() EMPTY items won't be added.
     */
    public static String joinNotEmpty(CharSequence delimiter, Iterable tokens) {
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token : tokens) {
            if (!isEmpty(toString(token))) {
                if (firstTime) {
                    firstTime = false;
                } else {
                    sb.append(delimiter);
                }
                sb.append(token);
            }
        }
        return sb.toString();
    }

    public static String firstLine(String string) {
        if (string == null) return null;
        final int nextLineIndex = string.indexOf('\n');
        if (nextLineIndex > 0) return string.substring(0, nextLineIndex);
        return string;
    }

    /**
     * Splits this strings using the supplied {@code regularExpression}.
     */
    public static List<String> splitAndClearEmpty(ArrayList<String> strings, String regularExpression) {
        ArrayList<String> result = new ArrayList<>();
        for (String string : strings) {
            result.addAll(splitAndClearEmpty(string, regularExpression));
        }
        return result;
    }

    /**
     * Splits this string using the supplied {@code regularExpression}.
     */
    public static List<String> splitAndClearEmpty(String string, String regularExpression) {
        ArrayList<String> strings = new ArrayList<>();
        final String[] split = string.split(regularExpression);
        if (split.length == 0) {
            strings.add(string);
        } else {
            strings.addAll(Arrays.asList(split));
        }

        Iterator<String> iterator = strings.iterator();
        while (iterator.hasNext()) {
            String item = iterator.next();
            if (item == null || item.trim().length() == 0) {
                iterator.remove();
            }
        }

        return strings;
    }

    /**
     * Splits this strings using the supplied {@code regularExpression}.
     */
    public static String[] splitAndClear(String[] strings, String regularExpression) {
        ArrayList<String> result = new ArrayList<>();
        for (String string : strings) {
            result.addAll(splitAndClearEmpty(string, regularExpression));
        }
        return result.toArray(new String[result.size()]);
    }

    /**
     * Splits this string using the supplied {@code regularExpression}.
     */
    public static String[] splitAndClear(String string, String regularExpression) {
        ArrayList<String> strings = new ArrayList<>();
        final String[] split = string.split(regularExpression);
        if (split == null || split.length == 0) {
            strings.add(string);
        } else {
            strings.addAll(Arrays.asList(split));
        }

        Iterator<String> iterator = strings.iterator();
        while (iterator.hasNext()) {
            String item = iterator.next();
            if (item == null || item.trim().length() == 0) {
                iterator.remove();
            }
        }

        return strings.toArray(new String[strings.size()]);
    }

    /**
     * Parse int value from string
     */
    public static int getIntValue(String intNumber) {
        try {
            return Integer.parseInt(intNumber);
        } catch (NumberFormatException e) {
            return 0;
        }
    }
}
977105
public static boolean insnEqual(AbstractInsnNode node1, AbstractInsnNode node2)
	{
		if (node1 == null || node2 == null || node1.getOpcode() != node2.getOpcode())
			return false;

		switch (node2.getType())
		{
			case VAR_INSN:
				return varInsnEqual((VarInsnNode) node1, (VarInsnNode) node2);
			case TYPE_INSN:
				return typeInsnEqual((TypeInsnNode) node1, (TypeInsnNode) node2);
			case FIELD_INSN:
				return fieldInsnEqual((FieldInsnNode) node1, (FieldInsnNode) node2);
			case METHOD_INSN:
				return methodInsnEqual((MethodInsnNode) node1, (MethodInsnNode) node2);
			case LDC_INSN:
				return ldcInsnEqual((LdcInsnNode) node1, (LdcInsnNode) node2);
			case IINC_INSN:
				return iincInsnEqual((IincInsnNode) node1, (IincInsnNode) node2);
			case INT_INSN:
				return intInsnEqual((IntInsnNode) node1, (IntInsnNode) node2);
			default:
				return true;
		}
	}
1103383
function wrapTree(t) {
    var wt = {
      t: t,
      prelim: 0,
      mod: 0, 
      shift: 0, 
      change: 0,
      msel: 0,
      mser: 0,
    };
    t.x = 0;
    t.y = 0;
    if (size) {
      wt.x_size = 1;
      wt.y_size = 1;
    }
    else if (typeof nodeSize == "object") {  // fixed array
      wt.x_size = nodeSize[0];
      wt.y_size = nodeSize[1];
    }
    else {  // use nodeSize function
      var ns = nodeSize(t);
      wt.x_size = ns[0];
      wt.y_size = ns[1];
    }
    if (setNodeSizes) {
      t.x_size = wt.x_size;
      t.y_size = wt.y_size;
    }

    var children = [];
    var num_children = t.children ? t.children.length : 0;
    for (var i = 0; i < num_children; ++i) {
      children.push(wrapTree(t.children[i]));
    }
    wt.children = children;
    wt.num_children = num_children;

    return wt;
  }
294205
def get_tree_depth( self ):
        '''  '''
        if (self.children):
            depth = 1
            childDepths = []
            for child in self.children:
                childDepths.append( child.get_tree_depth() )
            return depth + max(childDepths)
        else:
            return 0
1069396
function BST(compareFn) {
  this.root = null;
  this._size = 0;
  /**
   * @var Comparator
   */
  this._comparator = new Comparator(compareFn);

  /**
   * Read-only property for the size of the tree
   */
  Object.defineProperty(this, 'size', {
    get: function () { return this._size; }.bind(this)
  });
}
253600
function countSubTreeDepth(scope) {
          var thisLevelDepth = 0,
              childNodes = scope.childNodes(),
              childNode,
              childDepth,
              i;
          if (!childNodes || childNodes.length === 0) {
            return 0;
          }
          for (i = childNodes.length - 1; i >= 0 ; i--) {
            childNode = childNodes[i],
            childDepth = 1 + countSubTreeDepth(childNode);
            thisLevelDepth = Math.max(thisLevelDepth, childDepth);
          }
          return thisLevelDepth;
        }
818226
private static int countTailoredNodes(long[] nodesArray, int i, int strength) {
        int count = 0;
        for(;;) {
            if(i == 0) { break; }
            long node = nodesArray[i];
            if(strengthFromNode(node) < strength) { break; }
            if(strengthFromNode(node) == strength) {
                if(isTailoredNode(node)) {
                    ++count;
                } else {
                    break;
                }
            }
            i = nextIndexFromNode(node);
        }
        return count;
    }
19085
private static int compare(Treenode item1, Treenode item2) {
        String label1 = item1.getLabel();
        String label2 = item2.getLabel();
        return label1 == label2 ? 0 : label1 == null ? -1 : label2 == null ? -1 : label1.compareToIgnoreCase(label2);
    }
661208
function glb(tree, node, key, comp, low) {
    if (node === tree.z) {
        return low;
    }
    else if (comp(key, node.key) >= 0) {
        // The node key is a valid lower bound, but may not be the greatest.
        // Take the right link in search of larger keys.
        return maxNode(node, glb(tree, node.r, key, comp, low), comp);
    }
    else {
        // Take the left link in search of smaller keys.
        return glb(tree, node.l, key, comp, low);
    }
}
244962
private float getDepScore(DependencyTree t1, DependencyTree t2, int depth){
		float score = 0.0f;
		float modify = getDepthModify(depth);
		if(modify == 0)
			return score;
		
		double sScore = getWordScore(t1, t2);
        if (sScore != 0)
            score += modify * sScore;
        else
            score += factor * modify * getTagScore(t1, t2);
		
		for(int i = 0; i < t1.leftChilds.size(); i++)
			for(int j = 0; j < t2.leftChilds.size(); j++)
				score += getDepScore(t1.leftChilds.get(i), t2.leftChilds.get(j), depth+1);
		
//		for(int i = 0; i < t1.leftChilds.size(); i++)
//			for(int j = 0; j < t2.rightChilds.size(); j++)
//				score += getDepScore(t1.leftChilds.get(i), t2.rightChilds.get(j), depth+1);
//		
//		for(int i = 0; i < t1.rightChilds.size(); i++)
//			for(int j = 0; j < t2.leftChilds.size(); j++)
//				score += getDepScore(t1.rightChilds.get(i), t2.leftChilds.get(j), depth+1);
		
		for(int i = 0; i < t1.rightChilds.size(); i++)
			for(int j = 0; j < t2.rightChilds.size(); j++)
				score += getDepScore(t1.rightChilds.get(i), t2.rightChilds.get(j), depth+1);
		
		return score;
	}
1182778
function tinf_build_fixed_trees(lt, dt) {
  var i;

  /* build fixed length tree */
  for (i = 0; i < 7; ++i) lt.table[i] = 0;

  lt.table[7] = 24;
  lt.table[8] = 152;
  lt.table[9] = 112;

  for (i = 0; i < 24; ++i) lt.trans[i] = 256 + i;
  for (i = 0; i < 144; ++i) lt.trans[24 + i] = i;
  for (i = 0; i < 8; ++i) lt.trans[24 + 144 + i] = 280 + i;
  for (i = 0; i < 112; ++i) lt.trans[24 + 144 + 8 + i] = 144 + i;

  /* build fixed distance tree */
  for (i = 0; i < 5; ++i) dt.table[i] = 0;

  dt.table[5] = 32;

  for (i = 0; i < 32; ++i) dt.trans[i] = i;
}
349803
@Override
  @SuppressWarnings("fallthrough")
  public Node optimizeSubtree(Node node) {
    switch (node.getToken()) {
      case THROW:
      case RETURN: {
        Node result = tryRemoveRedundantExit(node);
        if (result != node) {
          return result;
        }
        return tryReplaceExitWithBreak(node);
      }

      // TODO(johnlenz): Maybe remove redundant BREAK and CONTINUE. Overlaps
      // with MinimizeExitPoints.

      case NOT:
        tryMinimizeCondition(node.getFirstChild());
        return tryMinimizeNot(node);

      case IF:
        performConditionSubstitutions(node.getFirstChild());
        return tryMinimizeIf(node);

      case EXPR_RESULT:
        performConditionSubstitutions(node.getFirstChild());
        return tryMinimizeExprResult(node);

      case HOOK:
        performConditionSubstitutions(node.getFirstChild());
        return tryMinimizeHook(node);

      case WHILE:
      case DO:
        tryMinimizeCondition(NodeUtil.getConditionExpression(node));
        return node;

      case FOR:
        tryJoinForCondition(node);
        tryMinimizeCondition(NodeUtil.getConditionExpression(node));
        return node;

      case BLOCK:
        return tryReplaceIf(node);

      default:
        return node; //Nothing changed
    }
  }
868905
function sortNodesByDepth (graph) {
      // Build the map of nodes to their levels
      let nodesSortedByDepth = [];
      let index;
      for (index in graph.nodes) {
        if ({}.hasOwnProperty.call(graph.nodes, index)) {
          const node = graph.nodes[index];
          nodesSortedByDepth[node.rank] = nodesSortedByDepth[node.rank] || [];
          nodesSortedByDepth[node.rank].push(node);
        }
      }

      // Remove empty ranks (and normalize to base 0)
      nodesSortedByDepth = nodesSortedByDepth.reduce((a, n) => { a.push(n); return a; }, []);

      const maxNodesPerDepth = 30;
      for (let i = 0; i < nodesSortedByDepth.length; i++) {
        const nodesInDepth = nodesSortedByDepth[i];
        if (nodesInDepth.length > maxNodesPerDepth) {
          const nodesToKeep = Math.min((nodesInDepth.length / 2) - 1, maxNodesPerDepth);
          const newNodeDepth = nodesInDepth.splice(nodesToKeep);
          nodesSortedByDepth.splice(i + 1, 0, newNodeDepth);
        }
      }

      return nodesSortedByDepth;
    }
1314323
public int depth(Tree node) {
        Tree p = node.parent(this);
        if (this == node) {
            return 0;
        }
        if (p == null) {
            return -1;
        }
        int depth = 1;
        while (this != p) {
            p = p.parent(this);
            depth++;
        }
        return depth;
    }