protected override SyntaxToken VisitFunction(FunctionSyntaxToken token)
        {
            SyntaxToken arg  = token.Arguments[0];
            SyntaxToken diff = this.Visit(arg);
            SyntaxToken one  = SyntaxToken.Constant(1);
            SyntaxToken two  = SyntaxToken.Constant(2);
            SyntaxToken result;

            switch (token.Type)
            {
            case FunctionType.Sin:
                result = SyntaxToken.Cos(arg);
                break;

            case FunctionType.Cos:
                result = SyntaxToken.Negate(SyntaxToken.Sin(arg));
                break;

            case FunctionType.Tan:
                result = SyntaxToken.Add(one, SyntaxToken.Pow(SyntaxToken.Tan(arg), two));
                break;

            case FunctionType.Cot:
                result = SyntaxToken.Negate(SyntaxToken.Add(one, SyntaxToken.Pow(SyntaxToken.Cot(arg), two)));
                break;

            case FunctionType.Asin:
                result = SyntaxToken.Divide(one, SyntaxToken.Root(SyntaxToken.Subtract(one, SyntaxToken.Pow(arg, two)), two));
                break;

            case FunctionType.Acos:
                result = -(one / SyntaxToken.Root(one - SyntaxToken.Pow(arg, two), two));
                break;

            case FunctionType.Atan:
                result = one / (one + SyntaxToken.Pow(arg, two));
                break;

            case FunctionType.Acot:
                result = -(one / (one + SyntaxToken.Pow(arg, two)));
                break;

            case FunctionType.Log:
                SyntaxToken b = token.Arguments[1];
                result = one / (arg * SyntaxToken.Ln(b));
                break;

            case FunctionType.Ln:
                result = one / arg;
                break;

            case FunctionType.Abs:
                result = arg / SyntaxToken.Abs(arg);
                break;

            case FunctionType.Unsupported:
            default: throw new NotSupportedException();
            }
            return(result * diff);
        }