code: function simplify(node) {
    const substeps = [];
    const simplifyFunctions = [
      arithmeticSearch,                       // e.g. 2*9 -> 18
      rearrangeCoefficient,  // e.g. x*5 -> 5x
      collectAndCombineSearch,                        // e.g 2x*4x -> 8x^2
      distributeAndSimplifyOperationNode, // e.g. (2+x)(3+x) -> 2*(3+x) recurses
    ];
  
    let newNode = clone(node);
    for (let i = 0; i < newNode.args.length; i++) {
      for (let j = 0; j < simplifyFunctions.length; j++) {
        const childStatus = simplifyFunctions[j](newNode.args[i]);
        if (childStatus.hasChanged()) {
          const status = Node.Status.childChanged(newNode, childStatus, i);
          substeps.push(status);
          newNode = Node.Status.resetChangeGroups(status.newNode);
        }
      }
    }
  
    // possible in cases like 2(x + y) -> 2x + 2y -> doesn't need simplifying
    if (substeps.length === 0) {
      return Node.Status.noChange(node);
    }
    else {
      return Node.Status.nodeChanged(
        ChangeTypes.SIMPLIFY_TERMS, node, newNode, false, substeps);
    }
  }
docs: Simplifies a sum of terms that are a result of distribution. e.g. (2x+3)*(4x+5) -distribute-> 2x*(4x+5) + 3*(4x+5) <- 2 terms to simplify e.g. 2x*(4x+5) --distribute--> 2x*4x + 2x*5 --simplify--> 8x^2 + 10x Returns a Node.Status object.