public Node differentiate(
      ASTFunNode node, String var, Node[] children, Node[] dchildren, DJep djep)
      throws ParseException {
    OperatorSet opset = djep.getOperatorSet();
    NodeFactory nf = djep.getNodeFactory();
    Operator op = opset.getMultiply();
    if (mulOp != null) op = mulOp;

    int nchild = node.jjtGetNumChildren();
    if (nchild == 2)
      return nf.buildOperatorNode(
          opset.getAdd(),
          nf.buildOperatorNode(op, dchildren[0], djep.deepCopy(children[1])),
          nf.buildOperatorNode(op, djep.deepCopy(children[0]), dchildren[1]));

    Node sums[] = new Node[nchild];
    for (int i = 0; i < nchild; ++i) {
      Node terms[] = new Node[nchild];
      for (int j = 0; j < nchild; ++j) terms[j] = children[j];
      terms[i] = dchildren[i];
      sums[i] = nf.buildOperatorNode(op, terms);
    }
    Node res = nf.buildOperatorNode(opset.getAdd(), sums);
    return res;

    // throw new ParseException("Too many children "+nchild+" for "+node+"\n");
  }
  /**
   * Differentiates a variable. May want to alter behaviour when using multi equation as diff(f,x)
   * might not be zero.
   *
   * @return 1 if the variable has the same name as data, 0 if the variable has a different name.
   */
  public Object visit(ASTVarNode node, Object data) throws ParseException {
    String varName = (String) data;
    XVariable var = (XVariable) node.getVar();
    PartialDerivative deriv = null;
    if (var instanceof DVariable) {
      DVariable difvar = (DVariable) var;
      if (varName.equals(var.getName())) return nf.buildConstantNode(tu.getONE());
      else if (isConstantVar(var)) return nf.buildConstantNode(tu.getZERO());

      deriv = difvar.findDerivative(varName, localDJep);
    } else if (var instanceof PartialDerivative) {
      if (isConstantVar(var)) return nf.buildConstantNode(tu.getZERO());

      PartialDerivative pvar = (PartialDerivative) var;
      DVariable dvar = pvar.getRoot();
      deriv = dvar.findDerivative(pvar, varName, localDJep);

    } else throw new ParseException("Encountered non differentiable variable");

    Node eqn = deriv.getEquation();
    if (eqn instanceof ASTVarNode) return nf.buildVariableNode(((ASTVarNode) eqn).getVar());
    if (eqn instanceof ASTConstant) return nf.buildConstantNode(((ASTConstant) eqn).getValue());

    return nf.buildVariableNode(deriv);
  }
 /**
  * Differentiates a constant.
  *
  * @return 0 derivatives of constants are always zero.
  */
 public Object visit(ASTConstant node, Object data) throws ParseException {
   return nf.buildConstantNode(tu.getZERO());
 }