/// <summary>
        /// Gets an object initializer expression.
        /// </summary>
        /// <param name="parentProxy">Represents the parent item.</param>
        /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param>
        /// <returns>Returns the expression.</returns>
        private ObjectInitializerExpression GetObjectInitializerExpression(CodeUnitProxy parentProxy, bool unsafeCode)
        {
            Param.AssertNotNull(parentProxy, "parentProxy");
            Param.Ignore(unsafeCode);

            this.AdvanceToNextCodeSymbol(parentProxy);
            var expressionProxy = new CodeUnitProxy(this.document);
            var initializerExpressions = new List<EqualsExpression>();

            // Add and move past the opening curly bracket.
            BracketToken openingBracket = (BracketToken)this.GetToken(expressionProxy, TokenType.OpenCurlyBracket, SymbolType.OpenCurlyBracket);

            while (true)
            {
                // If the next symbol is the closing curly bracket, then we are done.
                Symbol symbol = this.PeekNextSymbol();
                if (symbol.SymbolType == SymbolType.CloseCurlyBracket)
                {
                    break;
                }

                var initializerExpressionProxy = new CodeUnitProxy(this.document);

                // Get the identifier.
                this.AdvanceToNextCodeSymbol(expressionProxy);
                LiteralExpression identifier = this.GetLiteralExpression(initializerExpressionProxy, unsafeCode);

                // Get the equals sign.
                symbol = this.PeekNextSymbol();
                if (symbol.SymbolType != SymbolType.Equals)
                {
                    throw this.CreateSyntaxException();
                }

                this.GetOperatorSymbolToken(initializerExpressionProxy, OperatorType.Equals);

                // Get the initializer value. If this begins with an opening curly bracket,
                // this is an embedded object or collection initializer. Otherwise, it is
                // some other kind of expression.
                Expression initializerValue = null;

                symbol = this.PeekNextSymbol();
                if (symbol.SymbolType == SymbolType.OpenCurlyBracket)
                {
                    initializerValue = this.GetObjectOrCollectionInitializerExpression(initializerExpressionProxy, unsafeCode);
                }
                else
                {
                    initializerValue = this.GetNextExpression(initializerExpressionProxy, ExpressionPrecedence.None, unsafeCode);
                }

                // Create and add this initializer.
                var initializerExpression = new EqualsExpression(initializerExpressionProxy, identifier, initializerValue);
                expressionProxy.Children.Add(initializerExpression);
                initializerExpressions.Add(initializerExpression);

                // Check whether we're done.
                symbol = this.PeekNextSymbol();
                if (symbol.SymbolType == SymbolType.Comma)
                {
                    this.GetToken(expressionProxy, TokenType.Comma, SymbolType.Comma);

                    // If the next symbol after this is the closing curly bracket, then we are done.
                    symbol = this.PeekNextSymbol();
                    if (symbol.SymbolType == SymbolType.CloseCurlyBracket)
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }

            // Add and move past the closing curly bracket.
            BracketToken closingBracket = (BracketToken)this.GetToken(expressionProxy, TokenType.CloseCurlyBracket, SymbolType.CloseCurlyBracket);

            openingBracket.MatchingBracket = closingBracket;
            closingBracket.MatchingBracket = openingBracket;

            // Create and return the expression.
            var expression = new ObjectInitializerExpression(expressionProxy, initializerExpressions.AsReadOnly());
            parentProxy.Children.Add(expression);

            return expression;
        }
        /// <summary>
        /// Reads an assignment expression.
        /// </summary>
        /// <param name="expressionProxy">Proxy object for the expression being created.</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>
        /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param>
        /// <returns>Returns the expression.</returns>
        private AssignmentExpression GetAssignmentExpression(
            CodeUnitProxy expressionProxy, Expression leftHandSide, ExpressionPrecedence previousPrecedence, bool unsafeCode)
        {
            Param.AssertNotNull(expressionProxy, "expressionProxy");
            Param.AssertNotNull(leftHandSide, "leftHandSide");
            Param.Ignore(previousPrecedence);
            Param.Ignore(unsafeCode);

            AssignmentExpression expression = null;

            // Read the details of the expression.
            OperatorSymbolToken operatorToken = this.PeekOperatorSymbolToken();
            CsLanguageService.Debug.Assert(operatorToken.Category == OperatorCategory.Assignment, "Expected an assignment 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))
            {
                // Create the operator toke again and save it.
                operatorToken = this.GetOperatorSymbolToken(expressionProxy);

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

                // Get the expression operator type.
                switch (operatorToken.SymbolType)
                {
                    case OperatorType.Equals:
                        expression = new EqualsExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.PlusEquals:
                        expression = new PlusEqualsExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.MinusEquals:
                        expression = new MinusEqualsExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.MultiplicationEquals:
                        expression = new MultiplicationEqualsExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.DivisionEquals:
                        expression = new DivisionEqualsExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.AndEquals:
                        expression = new AndEqualsExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.OrEquals:
                        expression = new OrEqualsExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.XorEquals:
                        expression = new XorEqualsExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.ModEquals:
                        expression = new ModEqualsExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.LeftShiftEquals:
                        expression = new LeftShiftEqualsExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.RightShiftEquals:
                        expression = new RightShiftEqualsExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

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

            return expression;
        }