lib/integral.js
function(expr, context, subIntegral) {
      if(expr.type === "OperatorNode" && expr.op === '*') {
        var wasChange = false;
        var isTotalPositive = true;
        var processedArgs = [];
        expr.args.forEach(function(expr) {
          if(expr.type === "OperatorNode" && expr.args.length === 1 && (expr.op === '+' || expr.op === '-')) {
            wasChange = true;
            isTotalPositive = isTotalPositive ^ (expr.op === '-');
            processedArgs.push(expr.args[0]);
          } else {
            processedArgs.push(expr);
          }
        });

        if(wasChange) {
          var int = subIntegral(new OperatorNode('*', 'multiply', processedArgs), context, "removing unary +/- from factors");
          if(int) {
            return isTotalPositive ? int : new OperatorNode('-', 'unaryMinus', [int]);
          }
        }
      }
    }
function(expr, context, subIntegral) {
      if(expr.type === "OperatorNode" && expr.op === '*') {
        var wasChange = false;
        var isTotalPositive = true;
        var processedArgs = [];
        expr.args.forEach(function(expr) {
          if(expr.type === "OperatorNode" && expr.args.length === 1 && (expr.op === '+' || expr.op === '-')) {
            wasChange = true;
            isTotalPositive = isTotalPositive ^ (expr.op === '-');
            processedArgs.push(expr.args[0]);
          } else {
            processedArgs.push(expr);
          }
        });

        if(wasChange) {
          var int = subIntegral(new OperatorNode('*', 'multiply', processedArgs), context, "removing unary +/- from factors");
          if(int) {
            return isTotalPositive ? int : new OperatorNode('-', 'unaryMinus', [int]);
          }
        }
      }
    }
integral(f(x) * +/-g(x), x) = +/-integral(f(x) * g(x), x)