/// <summary>
        /// Generates CIL for the addition operation.
        /// </summary>
        /// <param name="generator"> The generator to output the CIL to. </param>
        /// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
        private void GenerateAdd(ILGenerator generator, OptimizationInfo optimizationInfo)
        {
            // Get the statically-determined types of the left and right operands.
            Type leftType  = this.Left.GetResultType(optimizationInfo);
            Type rightType = this.Right.GetResultType(optimizationInfo);

            // The add operator adds two strings together if at least one of the operands
            // is a string, otherwise it adds two numbers.
            if (PrimitiveTypeUtilities.IsString(leftType) || PrimitiveTypeUtilities.IsString(rightType))
            {
                // If at least one of the operands is a string, then the add operator concatenates.

                // Load the left-hand side onto the stack.
                this.Left.GenerateCode(generator, optimizationInfo);

                // Convert the operand to a concatenated string.
                EmitConversion.ToPrimitive(generator, leftType, PrimitiveTypeHint.None);
                EmitConversion.ToConcatenatedString(generator, leftType);

                // Load the right-hand side onto the stack.
                this.Right.GenerateCode(generator, optimizationInfo);

                if (rightType == typeof(string))
                {
                    // Concatenate the two strings.
                    generator.Call(ReflectionHelpers.ConcatenatedString_Concatenate_String);
                }
                else if (rightType == typeof(ConcatenatedString))
                {
                    // Concatenate the two strings.
                    generator.Call(ReflectionHelpers.ConcatenatedString_Concatenate_ConcatenatedString);
                }
                else
                {
                    // Convert the operand to an object.
                    EmitConversion.ToPrimitive(generator, rightType, PrimitiveTypeHint.None);
                    EmitConversion.ToAny(generator, rightType);

                    // Concatenate the two strings.
                    generator.Call(ReflectionHelpers.ConcatenatedString_Concatenate_Object);
                }
            }
            else if (leftType != typeof(object) && leftType != typeof(Library.ObjectInstance) &&
                     rightType != typeof(object) && rightType != typeof(Library.ObjectInstance))
            {
                // Neither of the operands are strings.

                // If the two types are numeric integers, retain the one with the most accuracy.
                Type numeric = TypeConverter.MostAccurateInteger(leftType, rightType);

                if (numeric == null)
                {
                    // Load the left hand side onto the stack.
                    this.Left.GenerateCode(generator, optimizationInfo);

                    // Convert the operand to a number.
                    EmitConversion.ToNumber(generator, leftType);

                    // Load the right hand side onto the stack.
                    this.Right.GenerateCode(generator, optimizationInfo);

                    // Convert the operand to a number.
                    EmitConversion.ToNumber(generator, rightType);

                    // Add the two numbers.
                    generator.Add();
                }
                else
                {
                    // Use them both converted to 'numeric'

                    // Load the left hand side onto the stack.
                    this.Left.GenerateCode(generator, optimizationInfo);

                    // Convert the operand to a number.
                    EmitConversion.ToNumber(generator, leftType, numeric);

                    // Load the right hand side onto the stack.
                    this.Right.GenerateCode(generator, optimizationInfo);

                    // Convert the operand to a number.
                    EmitConversion.ToNumber(generator, rightType, numeric);

                    // Add the two numbers.
                    generator.Add();
                }
            }
            else
            {
                // It is unknown whether the operands are strings.

                // Load the left hand side onto the stack.
                this.Left.GenerateCode(generator, optimizationInfo);
                EmitConversion.ToAny(generator, leftType);

                // Load the right hand side onto the stack.
                this.Right.GenerateCode(generator, optimizationInfo);
                EmitConversion.ToAny(generator, rightType);

                // Add the two objects.
                generator.Call(ReflectionHelpers.TypeUtilities_Add);
            }
        }