anchor.diff:    Expression asE() => new Exponential(second * new Ln(first));
   }
   
  -//abstract class MathFunction extends Expression {
  -//  MathFunction(this.)
  -//}
  +/**
  + * A function with an arbitrary number of arguments.
  + * 
  + * **Note:** Functions do not offer auto-wrapping of arguments into [Literal]s.
  + */
  +abstract class MathFunction extends Expression {
  +  /// Name of this function.
  +  String name;
  +  
  +  /// List of arguments of this function.
  +  List<Expression> args;
  +  
  +  /**
  +   * Creates a new function with the given name and arguments.
  +   */
  +  MathFunction(this.name, this.args);
  +  
  +  /**
  +   * Creates a new unary function with one argument.
  +   */
  +  MathFunction.unary(this.name, Expression arg): this.args = [arg];
  +  
  +  /**
  +   * Creates a new binary function with two arguments.
  +   */
  +  MathFunction.binary(this.name, Expression arg1, Expression arg2): this.args = [arg1, arg2];
  +  
  +  /**
  +   * Returns the i-th parameter of this function.
  +   */
  +  Expression getParam(int i) => args[i];
  +}
   
   /**
    * The exponential function.
    */
  -class Exponential extends UnaryOperator {
  +class Exponential extends MathFunction {
   
     /**
      * Creates a exponential operation on the given expressions.
      * 
      * For example, to create e^4:
  -   *     exp = new Exponential(4);
  -   * 
  -   * or:
      *     exp = new Exponential(new Number(4));
      */
  -  Exponential(exp): super(exp);
  +  Exponential(exp): super.unary("exp", exp);
  +  
  +  /// The exponent of this exponential function.
  +  Expression get exp => getParam(0);
  +  
     Expression derive(String toVar) => new Times(this, exp.derive(toVar));
  +    
     String toString() => 'e^(${exp.toString()})';
   }
   
   /**
    * The logarithm function.
    */
  -class Log extends BinaryOperator {
  +class Log extends MathFunction {
     
     /**
      * Creates a logarithm function with given base and argument.
      * 
      * For example, to create log_10(2):
  -   *     log = new Log(10, 2);
  +   *     base = new Number(10);
  +   *     arg = new Number(2);
  +   *     log = new Log(base, arg);
      *     
      * To create a naturally based logarithm, see [Ln].
      */
  -  Log(base, arg): super(base, arg);
  -  
  -  Expression get base => first;
  -  Expression get arg => second;
  +  Log(Expression base, Expression arg): super.binary("log", base, arg);
  +  
  +  /**
  +   * Creates a natural logarithm.
  +   * Must only be used internally by the Ln class.
  +   */
  +  Log._ln(arg): super.binary("ln", new Number(Math.E), arg);
  +  
  +  /// The base of this logarithm.
  +  Expression get base => getParam(0);
  +  
  +  /// The argument of this logarithm.
  +  Expression get arg => getParam(1);
     
     Expression derive(String toVar) => this.asNaturalLogarithm().derive(toVar);
  +    
     String toString() => 'log_${base.toString()}(${arg.toString()})';
     
     /**
  
positive.code:     
      throw new ArgumentError('${arg} is not a valid expression!');
    }
  }
  
  /**
  
negative.code:   Power(x, exp): super(x, exp);
    
    Expression derive(String toVar) => this.asE().derive(toVar);
    
    /**
     * Possible simplifications:
     * 
     * 1. 0^x = 0
     * 2. 1^x = 1
     * 3. x^0 = 1
     * 4. x^1 = x
     */
    Expression simplify() {
      Expression baseOp = first.simplify();
      Expression exponentOp = second.simplify();
     
      //TODO unboxing
      /*
      bool baseNegative = false, expNegative = false;
      
      
      // unbox unary minuses
      if (baseOp is UnaryMinus) {
        baseOp = baseOp.exp;
        baseNegative = !baseNegative;
      }
      if (exponentOp is UnaryMinus) {
        exponentOp = exponentOp.exp;
        expNegative = !expNegative;
      }
      */
      
      if (_isNumber(baseOp, 0)) {
        return baseOp; // 0^x = 0
      }
      
      if (_isNumber(baseOp, 1)) {
        return baseOp; // 1^x = 1
      }
      
      if (_isNumber(exponentOp, 0)) {
        return new Number(1); // x^0 = 1
      }
      
      if (_isNumber(exponentOp, 1)) {
        return baseOp; // x^1 = x
      }
      
      return new Power(baseOp, exponentOp);
    }
    
    String toString() => '(${first.toString()}^${second.toString()})';
    
    /**
  