private bool IsValueExpression(Expression expression)
        {
            if (expression is LiteralExpression)
            {
                CsTokenType tokenType = ((LiteralExpression)expression).Token.CsTokenType;

                return(tokenType == CsTokenType.Number ||
                       tokenType == CsTokenType.String ||
                       tokenType == CsTokenType.Null ||
                       tokenType == CsTokenType.True ||
                       tokenType == CsTokenType.False);
            }

            if (expression is ParenthesizedExpression)
            {
                return(this.IsValueExpression(((ParenthesizedExpression)expression).InnerExpression));
            }

            if (expression is RelationalExpression)
            {
                RelationalExpression re = (RelationalExpression)expression;
                return(this.IsValueExpression(re.LeftHandSide) && this.IsValueExpression(re.RightHandSide));
            }

            if (expression is ArithmeticExpression)
            {
                ArithmeticExpression ae = (ArithmeticExpression)expression;
                return(this.IsValueExpression(ae.LeftHandSide) && this.IsValueExpression(ae.RightHandSide));
            }

            return(false);
        }
        /// <summary>
        /// Checks whether parenthesis are needed within the arithmetic expressions.
        /// </summary>
        /// <param name="element">
        /// The parent element.
        /// </param>
        /// <param name="expression">
        /// The parent arithmetic expression.
        /// </param>
        /// <param name="childExpression">
        /// The child arithmetic expression.
        /// </param>
        /// <returns>
        /// Returns true if there is no violation, or false if there is a violation.
        /// </returns>
        private bool CheckArithmeticParenthesisForExpressionAndChild(CsElement element, ArithmeticExpression expression, ArithmeticExpression childExpression)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(expression, "expression");
            Param.AssertNotNull(childExpression, "childExpression");

            // Parenthesis are only required when the two expressions are not the same operator,
            // and when the two operators come from different families. 
            if (expression.OperatorType != childExpression.OperatorType)
            {
                bool sameFamily = ((expression.OperatorType == ArithmeticExpression.Operator.Addition
                                    || expression.OperatorType == ArithmeticExpression.Operator.Subtraction)
                                   && (childExpression.OperatorType == ArithmeticExpression.Operator.Addition
                                       || childExpression.OperatorType == ArithmeticExpression.Operator.Subtraction))
                                  || ((expression.OperatorType == ArithmeticExpression.Operator.Multiplication
                                       || expression.OperatorType == ArithmeticExpression.Operator.Division)
                                      && (childExpression.OperatorType == ArithmeticExpression.Operator.Multiplication
                                          || childExpression.OperatorType == ArithmeticExpression.Operator.Division))
                                  || ((expression.OperatorType == ArithmeticExpression.Operator.LeftShift
                                       || expression.OperatorType == ArithmeticExpression.Operator.RightShift)
                                      && (childExpression.OperatorType == ArithmeticExpression.Operator.LeftShift
                                          || childExpression.OperatorType == ArithmeticExpression.Operator.RightShift));

                if (!sameFamily)
                {
                    this.AddViolation(element, expression.LineNumber, Rules.ArithmeticExpressionsMustDeclarePrecedence);
                    return false;
                }
            }

            return true;
        }
        /// <summary>
        /// Checks that parenthesis are used correctly within an arithmetic expression.
        /// </summary>
        /// <param name="element">
        /// The parent element.
        /// </param>
        /// <param name="expression">
        /// The expression to check.
        /// </param>
        private void CheckArithmeticExpressionParenthesis(CsElement element, ArithmeticExpression expression)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(expression, "expression");

            if (expression.LeftHandSide.ExpressionType == ExpressionType.Arithmetic)
            {
                if (!this.CheckArithmeticParenthesisForExpressionAndChild(element, expression, (ArithmeticExpression)expression.LeftHandSide))
                {
                    return;
                }
            }

            if (expression.RightHandSide.ExpressionType == ExpressionType.Arithmetic)
            {
                this.CheckArithmeticParenthesisForExpressionAndChild(element, expression, (ArithmeticExpression)expression.RightHandSide);
            }
        }
        /// <summary>
        /// Reads an arithmetic expression.
        /// </summary>
        /// <param name="leftHandSide">
        /// The expression on the left hand side of the operator.
        /// </param>
        /// <param name="previousPrecedence">
        /// The precedence of the expression just before this one.
        /// </param>
        /// <param name="parentReference">
        /// The parent code unit.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the code being parsed resides in an unsafe code block.
        /// </param>
        /// <returns>
        /// Returns the expression.
        /// </returns>
        private ArithmeticExpression GetArithmeticExpression(
            Expression leftHandSide, ExpressionPrecedence previousPrecedence, Reference<ICodePart> parentReference, bool unsafeCode)
        {
            Param.AssertNotNull(leftHandSide, "leftHandSide");
            Param.Ignore(previousPrecedence);
            Param.AssertNotNull(parentReference, "parentReference");
            Param.Ignore(unsafeCode);

            ArithmeticExpression expression = null;
            Reference<ICodePart> expressionReference = new Reference<ICodePart>();

            // Read the details of the expression.
            OperatorSymbol operatorToken = this.PeekOperatorToken(parentReference, expressionReference);
            Debug.Assert(
                operatorToken.Category == OperatorCategory.Arithmetic || operatorToken.Category == OperatorCategory.Shift, "Expected an arithmetic or shift operator");

            // Check the precedence of the operators to make sure we can gather this statement now.
            ExpressionPrecedence precedence = GetOperatorPrecedence(operatorToken.SymbolType);
            if (CheckPrecedence(previousPrecedence, precedence))
            {
                // Add the operator token to the document and advance the symbol manager up to it.
                this.symbols.Advance();
                this.tokens.Add(operatorToken);

                // Get the expression on the right-hand side of the operator.
                Expression rightHandSide = this.GetOperatorRightHandExpression(precedence, expressionReference, unsafeCode);

                // Create the partial token list for the expression.
                CsTokenList partialTokens = new CsTokenList(this.tokens, leftHandSide.Tokens.First, this.tokens.Last);

                // Get the expression operator type.
                ArithmeticExpression.Operator type;
                switch (operatorToken.SymbolType)
                {
                    case OperatorType.Plus:
                        type = ArithmeticExpression.Operator.Addition;
                        break;

                    case OperatorType.Minus:
                        type = ArithmeticExpression.Operator.Subtraction;
                        break;

                    case OperatorType.Multiplication:
                        type = ArithmeticExpression.Operator.Multiplication;
                        break;

                    case OperatorType.Division:
                        type = ArithmeticExpression.Operator.Division;
                        break;

                    case OperatorType.Mod:
                        type = ArithmeticExpression.Operator.Mod;
                        break;

                    case OperatorType.LeftShift:
                        type = ArithmeticExpression.Operator.LeftShift;
                        break;

                    case OperatorType.RightShift:
                        type = ArithmeticExpression.Operator.RightShift;
                        break;

                    default:
                        Debug.Fail("Unexpected operator type");
                        throw new InvalidOperationException();
                }

                // Create and return the expression.
                expression = new ArithmeticExpression(partialTokens, type, leftHandSide, rightHandSide);
                expressionReference.Target = expression;
            }

            return expression;
        }
        /// <summary>
        /// The save.
        /// </summary>
        /// <param name="operator">
        /// The operator.
        /// </param>
        private void Save(ArithmeticExpression.Operator @operator)
        {
            var operatorString = string.Empty;

            switch (@operator)
            {
                case ArithmeticExpression.Operator.Addition:
                    operatorString = "+";
                    break;
                case ArithmeticExpression.Operator.Division:
                    operatorString = "/";
                    break;
                case ArithmeticExpression.Operator.LeftShift:
                    operatorString = "<<";
                    break;
                case ArithmeticExpression.Operator.Mod:
                    operatorString = "%";
                    break;
                case ArithmeticExpression.Operator.Multiplication:
                    operatorString = "*";
                    break;
                case ArithmeticExpression.Operator.RightShift:
                    operatorString = ">>";
                    break;
                case ArithmeticExpression.Operator.Subtraction:
                    operatorString = "-";
                    break;
                default:
                    break;
            }

            this.cppWriter.Write(' ');
            this.cppWriter.Write(operatorString);
            this.cppWriter.Write(' ');
        }
 /// <summary>
 /// The save.
 /// </summary>
 /// <param name="arithmeticExpression">
 /// The arithmetic expression.
 /// </param>
 private void Save(ArithmeticExpression arithmeticExpression)
 {
     @switch(arithmeticExpression.LeftHandSide);
     this.Save(arithmeticExpression.OperatorType);
     @switch(arithmeticExpression.RightHandSide);
 }