/// <summary>
        /// Reads a relational 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 part.</param>
        /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param>
        /// <returns>Returns the expression.</returns>
        private RelationalExpression GetRelationalExpression(
            Expression leftHandSide, ExpressionPrecedence previousPrecedence, Reference<ICodePart> parentReference, bool unsafeCode)
        {
            Param.AssertNotNull(leftHandSide, "leftHandSide");
            Param.Ignore(previousPrecedence);
            Param.AssertNotNull(parentReference, "parentReference");
            Param.Ignore(unsafeCode);

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

            // Read the details of the expression.
            OperatorSymbol operatorToken = this.PeekOperatorToken(parentReference, expressionReference);
            Debug.Assert(operatorToken.Category == OperatorCategory.Relational, "Expected a relational 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.
                RelationalExpression.Operator type;
                switch (operatorToken.SymbolType)
                {
                    case OperatorType.ConditionalEquals:
                        type = RelationalExpression.Operator.EqualTo;
                        break;

                    case OperatorType.NotEquals:
                        type = RelationalExpression.Operator.NotEqualTo;
                        break;

                    case OperatorType.GreaterThan:
                        type = RelationalExpression.Operator.GreaterThan;
                        break;

                    case OperatorType.GreaterThanOrEquals:
                        type = RelationalExpression.Operator.GreaterThanOrEqualTo;
                        break;

                    case OperatorType.LessThan:
                        type = RelationalExpression.Operator.LessThan;
                        break;

                    case OperatorType.LessThanOrEquals:
                        type = RelationalExpression.Operator.LessThanOrEqualTo;
                        break;

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

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

            return expression;
        }
        /// <summary>
        /// Reads a relational expression.
        /// </summary>
        /// <param name="sourceCode">The file containing the expression.</param>
        /// <param name="parentReference">The parent code unit.</param>
        /// <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>
        /// <returns>Returns the expression.</returns>
        private RelationalExpression GetConditionalPreprocessorEqualityExpression(
            SourceCode sourceCode, Reference<ICodePart> parentReference, Expression leftHandSide, ExpressionPrecedence previousPrecedence)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parentReference, "parentReference");
            Param.AssertNotNull(leftHandSide, "leftHandSide");
            Param.Ignore(previousPrecedence);

            RelationalExpression expression = null;

            this.AdvanceToNextConditionalDirectiveCodeSymbol(parentReference);
            Symbol firstSymbol = this.symbols.Peek(1);
            if (firstSymbol == null)
            {
                throw new SyntaxException(sourceCode, firstSymbol.LineNumber);
            }

            var expressionReference = new Reference<ICodePart>();

            // Create the operator symbol.
            OperatorType type;
            OperatorCategory category;
            GetOperatorType(firstSymbol, out type, out category);
            OperatorSymbol operatorToken = new OperatorSymbol(
                firstSymbol.Text, category, type, firstSymbol.Location, expressionReference, this.symbols.Generated);

            // 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.GetNextConditionalPreprocessorExpression(sourceCode, precedence);
                if (rightHandSide == null)
                {
                    throw new SyntaxException(sourceCode, operatorToken.LineNumber);
                }

                // 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.
                RelationalExpression.Operator relationalType;
                switch (operatorToken.SymbolType)
                {
                    case OperatorType.ConditionalEquals:
                        relationalType = RelationalExpression.Operator.EqualTo;
                        break;

                    case OperatorType.NotEquals:
                        relationalType = RelationalExpression.Operator.NotEqualTo;
                        break;

                    default:
                        throw new SyntaxException(sourceCode, operatorToken.LineNumber);
                }

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

            return expression;
        }