/// <summary>
        /// Parses and returns a field.
        /// </summary>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="elementReference">
        /// A reference to the element being created.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the code is marked as unsafe.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code is marked as generated code.
        /// </param>
        /// <param name="xmlHeader">
        /// The element's documentation header.
        /// </param>
        /// <param name="attributes">
        /// The attributes on the element.
        /// </param>
        /// <returns>
        /// Returns the element.
        /// </returns>
        private Field ParseField(
            CsElement parent, Reference<ICodePart> elementReference, bool unsafeCode, bool generated, XmlHeader xmlHeader, ICollection<Attribute> attributes)
        {
            Param.AssertNotNull(parent, "parent");
            Param.AssertNotNull(elementReference, "elementReference");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);
            Param.Ignore(xmlHeader);
            Param.Ignore(attributes);

            Node<CsToken> previousTokenNode = this.tokens.Last;

            // Get the modifiers and access.
            AccessModifierType accessModifier = AccessModifierType.Private;
            Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, FieldModifiers);

            unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe);

            // Get the field type.
            TypeToken fieldType = this.GetTypeToken(elementReference, unsafeCode, true);
            Node<CsToken> fieldTypeNode = this.tokens.InsertLast(fieldType);

            // Get all of the variable declarators.
            IList<VariableDeclaratorExpression> declarators = this.ParseFieldDeclarators(elementReference, unsafeCode, fieldType);

            if (declarators.Count == 0)
            {
                throw this.CreateSyntaxException();
            }

            VariableDeclarationExpression declarationExpression =
                new VariableDeclarationExpression(
                    new CsTokenList(this.tokens, declarators[0].Tokens.First, this.tokens.Last), new LiteralExpression(this.tokens, fieldTypeNode), declarators);

            // Create the field.
            Node<CsToken> firstTokenNode = previousTokenNode == null ? this.tokens.First : previousTokenNode.Next;
            CsTokenList declarationTokens = new CsTokenList(this.tokens, firstTokenNode, this.tokens.Last);
            Declaration declaration = new Declaration(declarationTokens, declarators[0].Identifier.Text, ElementType.Field, accessModifier, modifiers);

            Field field = new Field(this.document, parent, xmlHeader, attributes, declaration, fieldType, unsafeCode, generated);
            elementReference.Target = field;

            // Get the trailing semicolon.
            this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference));

            // Create the variable declaration statement and add it to the field.
            field.VariableDeclarationStatement = new VariableDeclarationStatement(
                new CsTokenList(this.tokens, declarators[0].Tokens.First, this.tokens.Last), field.Const, declarationExpression);

            return field;
        }
        /// <summary>
        /// Checks a field for compliance with naming prefix rules.
        /// </summary>
        /// <param name="field">
        /// The field element.
        /// </param>
        /// <param name="validPrefixes">
        /// A list of valid prefixes that should not be considered hungarian.
        /// </param>
        private void CheckFieldPrefix(Field field, Dictionary<string, string> validPrefixes)
        {
            Param.AssertNotNull(field, "field");
            Param.Ignore(validPrefixes);

            // Skip past any prefixes in the name.
            int index = NamingRules.MovePastPrefix(field.Declaration.Name);

            // Check whether the name starts with a lower-case letter.
            if (char.IsLower(field.Declaration.Name, index))
            {
                // Check for hungarian notation.
                this.CheckHungarian(field.Declaration.Name, index, field.LineNumber, field, validPrefixes);

                // Check casing on the field.
                if (field.Const)
                {
                    // Const fields must start with an upper-case letter.
                    this.AddViolation(field, field.LineNumber, Rules.ConstFieldNamesMustBeginWithUpperCaseLetter, field.Declaration.Name);
                }
                else if (field.AccessModifier == AccessModifierType.Public || field.AccessModifier == AccessModifierType.Internal
                         || field.AccessModifier == AccessModifierType.ProtectedInternal)
                {
                    // Public or internal fields must start with an upper-case letter.
                    this.AddViolation(field, field.LineNumber, Rules.AccessibleFieldsMustBeginWithUpperCaseLetter, field.Declaration.Name);
                }

                // Readonly fields non-private must start with an upper-case letter.
                if (field.Readonly && field.AccessModifier != AccessModifierType.Private)
                {
                    this.AddViolation(field, field.LineNumber, Rules.NonPrivateReadonlyFieldsMustBeginWithUpperCaseLetter, field.Declaration.Name);
                }

                // Readonly static fields must start with an upper-case letter.
                if (field.Readonly && field.Static)
                {
                    this.AddViolation(field, field.LineNumber, Rules.StaticReadonlyFieldsMustBeginWithUpperCaseLetter, field.Declaration.Name);
                }
            }
            else if (char.IsUpper(field.Declaration.Name, index))
            {
                // We check for IsUpper here as some languages don't have Upper/Lower case liek Chinese.
                // Constants must always start with an upper-case letter.
                if (field.Const)
                {
                    return;
                }

                // Readonly non-private fields must start with an upper-case letter.
                if (field.Readonly && field.AccessModifier != AccessModifierType.Private)
                {
                    return;
                }

                // Readonly static fields must start with an upper-case letter.
                if (field.Readonly && field.Static)
                {
                    return;
                }

                // Public, internal or protected-internal fields also must always start with an upper-case letter.
                if (field.AccessModifier == AccessModifierType.Public)
                {
                    return;
                }

                if (field.AccessModifier == AccessModifierType.Internal)
                {
                    return;
                }

                if (field.AccessModifier == AccessModifierType.ProtectedInternal)
                {
                    return;
                }

                this.AddViolation(field, field.LineNumber, Rules.FieldNamesMustBeginWithLowerCaseLetter, field.Declaration.Name);
            }
        }
        /// <summary>
        /// The save.
        /// </summary>
        /// <param name="fieldDeclaration">
        /// The field declaration.
        /// </param>
        private void Save(Field fieldDeclaration)
        {
            var isStatic = fieldDeclaration.Declaration.ContainsModifier(CsTokenType.Static);

            this.Save(fieldDeclaration.AccessModifier);
            this.headerWriter.Write(": ");

            if (isStatic)
            {
                this.headerWriter.Write("static ");
            }

            this.SwitchStreams();

            this.saveVariablesMode = SaveVariablesMode.DoNotSaveInitializers;

            this.Save(fieldDeclaration.VariableDeclarationStatement);

            this.saveVariablesMode = SaveVariablesMode.Default;

            this.SwitchStreams();

            this.headerWriter.WriteLine(';');

            if (isStatic || fieldDeclaration.VariableDeclarationStatement.Constant)
            {
                this.saveVariablesMode = SaveVariablesMode.DefaultSourceInitializers;

                this.Save(fieldDeclaration.VariableDeclarationStatement);

                this.saveVariablesMode = SaveVariablesMode.Default;

                this.cppWriter.WriteLine(';');
                this.cppWriter.WriteLine();
            }
        }