Service making names within a scope unique. Initialize a new instance for every scope.
        internal void WriteEntityContainer(IEdmEntityContainer container, string fullNamespace)
        {
            var camelCaseContainerName = container.Name;
            if (Context.EnableNamingAlias)
            {
                camelCaseContainerName = Customization.CustomizeNaming(camelCaseContainerName);
            }

            WriteClassStartForEntityContainer(container.Name, camelCaseContainerName, GetFixedName(camelCaseContainerName));
            WriteEntityContainerConstructor(container);

            if (Context.NeedResolveNameFromType)
            {
                WritePropertyRootNamespace(GetFixedName(camelCaseContainerName), Context.GetPrefixedNamespace(fullNamespace, this, false, false));
            }

            WriteResolveTypeFromName();
            WriteResolveNameFromType(camelCaseContainerName, fullNamespace);

            foreach (var entitySet in container.EntitySets())
            {
                var entitySetElementType = entitySet.EntityType();
                var entitySetElementTypeName = GetElementTypeName(entitySetElementType, container);

                var camelCaseEntitySetName = entitySet.Name;
                if (Context.EnableNamingAlias)
                {
                    camelCaseEntitySetName = Customization.CustomizeNaming(camelCaseEntitySetName);
                }

                WriteContextEntitySetProperty(camelCaseEntitySetName, GetFixedName(camelCaseEntitySetName), entitySet.Name, GetFixedName(entitySetElementTypeName));
                List<IEdmNavigationSource> edmNavigationSourceList = null;
                if (!Context.ElementTypeToNavigationSourceMap.TryGetValue(entitySet.EntityType(), out edmNavigationSourceList))
                {
                    edmNavigationSourceList = new List<IEdmNavigationSource>();
                    Context.ElementTypeToNavigationSourceMap.Add(entitySet.EntityType(), edmNavigationSourceList);
                }

                edmNavigationSourceList.Add(entitySet);
            }

            foreach (var entitySet in container.EntitySets())
            {
                var entitySetElementType = entitySet.EntityType();

                var entitySetElementTypeName = GetElementTypeName(entitySetElementType, container);

                var uniqueIdentifierService = new UniqueIdentifierService(/*IsLanguageCaseSensitive*/true);
                var parameterName = GetFixedName(uniqueIdentifierService.GetUniqueParameterName(entitySetElementType.Name));

                var camelCaseEntitySetName = entitySet.Name;
                if (Context.EnableNamingAlias)
                {
                    camelCaseEntitySetName = Customization.CustomizeNaming(camelCaseEntitySetName);
                }

                WriteContextAddToEntitySetMethod(camelCaseEntitySetName, entitySet.Name, GetFixedName(entitySetElementTypeName), parameterName);
            }

            foreach (var singleton in container.Singletons())
            {
                var singletonElementType = singleton.EntityType();
                var singletonElementTypeName = GetElementTypeName(singletonElementType, container);
                var camelCaseSingletonName = singleton.Name;
                if (Context.EnableNamingAlias)
                {
                    camelCaseSingletonName = Customization.CustomizeNaming(camelCaseSingletonName);
                }

                WriteContextSingletonProperty(camelCaseSingletonName, GetFixedName(camelCaseSingletonName), singleton.Name, singletonElementTypeName + "Single");

                List<IEdmNavigationSource> edmNavigationSourceList = null;
                if (Context.ElementTypeToNavigationSourceMap.TryGetValue(singleton.EntityType(), out edmNavigationSourceList))
                {
                    edmNavigationSourceList.Add(singleton);
                }
            }

            WriteGeneratedEdmModel(Utils.SerializeToString(Context.Edmx).Replace("\"", "\"\""));

            var hasOperationImport = container.OperationImports().OfType<IEdmOperationImport>().Any();
            foreach (var functionImport in container.OperationImports().OfType<IEdmFunctionImport>())
            {
                string parameterString, parameterTypes, parameterExpressionString, parameterValues;
                bool useEntityReference;
                GetParameterStrings(false, false, functionImport.Function.Parameters.ToArray(), out parameterString, out parameterTypes, out parameterExpressionString, out parameterValues, out useEntityReference);
                var returnTypeName = GetSourceOrReturnTypeName(functionImport.Function.ReturnType);
                var fixedContainerName = GetFixedName(functionImport.Container.Name);
                var isCollectionResult = functionImport.Function.ReturnType.IsCollection();
                var functionImportName = functionImport.Name;
                if (Context.EnableNamingAlias)
                {
                    functionImportName = Customization.CustomizeNaming(functionImportName);
                    fixedContainerName = Customization.CustomizeNaming(fixedContainerName);
                }

                if (functionImport.Function.ReturnType.IsCollection())
                {
                    WriteFunctionImportReturnCollectionResult(GetFixedName(functionImportName), functionImport.Name, returnTypeName, parameterString, parameterValues, functionImport.Function.IsComposable, useEntityReference);
                }
                else
                {
                    WriteFunctionImportReturnSingleResult(GetFixedName(functionImportName), functionImport.Name, returnTypeName, parameterString, parameterValues, functionImport.Function.IsComposable, functionImport.Function.ReturnType.IsEntity(), useEntityReference);
                }
            }

            foreach (var actionImport in container.OperationImports().OfType<IEdmActionImport>())
            {
                string parameterString, parameterTypes, parameterExpressionString, parameterValues;
                bool useEntityReference;
                GetParameterStrings(false, true, actionImport.Action.Parameters.ToArray(), out parameterString, out parameterTypes, out parameterExpressionString, out parameterValues, out useEntityReference);
                string returnTypeName = null;
                var fixedContainerName = GetFixedName(actionImport.Container.Name);

                if (actionImport.Action.ReturnType != null)
                {
                    returnTypeName = GetSourceOrReturnTypeName(actionImport.Action.ReturnType);
                    if (actionImport.Action.ReturnType.IsCollection())
                    {
                        returnTypeName = string.Format(DataServiceActionQueryOfTStructureTemplate, returnTypeName);
                    }
                    else
                    {
                        returnTypeName = string.Format(DataServiceActionQuerySingleOfTStructureTemplate, returnTypeName);
                    }
                }
                else
                {
                    returnTypeName = DataServiceActionQueryTypeName;
                }

                var actionImportName = actionImport.Name;
                if (Context.EnableNamingAlias)
                {
                    actionImportName = Customization.CustomizeNaming(actionImportName);
                    fixedContainerName = Customization.CustomizeNaming(fixedContainerName);
                }

                WriteActionImport(GetFixedName(actionImportName), actionImport.Name, returnTypeName, parameterString, parameterValues);
            }

            WriteClassEndForEntityContainer();
        }
        internal void WriteTypeStaticCreateMethod(string typeName, IEdmStructuredType structuredType)
        {
            Debug.Assert(structuredType != null, "structuredType != null");
            if (structuredType.IsAbstract)
            {
                return;
            }

            Func<IEdmProperty, bool> hasDefault = p => p.PropertyKind == EdmPropertyKind.Structural && ((IEdmStructuralProperty)p).DefaultValueString != null;

            if (Context.EnableNamingAlias)
            {
                typeName = Customization.CustomizeNaming(typeName);
            }

            var parameters = structuredType.Properties()
                .Where(p => !p.Type.IsNullable && !p.Type.IsCollection() && !hasDefault(p));
            if (!parameters.Any())
            {
                return;
            }

            WriteSummaryCommentForStaticCreateMethod(typeName);

            var uniqueIdentifierService = new UniqueIdentifierService( /*IsLanguageCaseSensitive*/true);
            var instanceName = GetFixedName(uniqueIdentifierService.GetUniqueParameterName(typeName));
            var propertyToParameterNamePairs = parameters
                .Select(p =>
                    new KeyValuePair<IEdmProperty, string>(p,
                        uniqueIdentifierService.GetUniqueParameterName(
                            IdentifierMappings.ContainsKey(p.Name) ? IdentifierMappings[p.Name] : p.Name)))
                .ToArray();

            foreach (var propertyToParameterNamePair in propertyToParameterNamePairs)
            {
                var propertyName = propertyToParameterNamePair.Key.Name;
                propertyName = IdentifierMappings.ContainsKey(propertyName) ?
                    IdentifierMappings[propertyName] : (Context.EnableNamingAlias ? Customization.CustomizeNaming(propertyName) : propertyName);
                WriteParameterCommentForStaticCreateMethod(propertyToParameterNamePair.Value, propertyName);
            }

            propertyToParameterNamePairs = propertyToParameterNamePairs
                .Select(p => p = new KeyValuePair<IEdmProperty, string>(p.Key, GetFixedName(p.Value)))
                .ToArray();

            WriteDeclarationStartForStaticCreateMethod(typeName, GetFixedName(typeName));
            WriteStaticCreateMethodParameters(propertyToParameterNamePairs);
            WriteDeclarationEndForStaticCreateMethod(GetFixedName(typeName), instanceName);

            foreach (var propertyToParameterNamePair in propertyToParameterNamePairs)
            {
                var property = propertyToParameterNamePair.Key;
                var parameterName = propertyToParameterNamePair.Value;

                Debug.Assert(!property.Type.IsCollection(), "!property.Type.IsCollection()");
                Debug.Assert(!property.Type.IsNullable, "!property.Type.IsNullable");

                // The static create method only sets non-nullable properties. We should add the null check if the type of the property is not a clr ValueType.
                // For now we add the null check if the property type is non-primitive. We should add the null check for non-ValueType primitives in the future.
                if (!property.Type.IsPrimitive() && !property.Type.IsEnum())
                {
                    WriteParameterNullCheckForStaticCreateMethod(parameterName);
                }

                var uniqIdentifier = IdentifierMappings.ContainsKey(property.Name) ?
                    IdentifierMappings[property.Name] : (Context.EnableNamingAlias ? Customization.CustomizeNaming(property.Name) : property.Name);
                WritePropertyValueAssignmentForStaticCreateMethod(instanceName,
                    GetFixedName(uniqIdentifier),
                    parameterName);
            }

            WriteMethodEndForStaticCreateMethod(instanceName);
        }
        // This is to solve duplicate names between property and type
        internal void SetPropertyIdentifierMappingsIfNameConflicts(string typeName, IEdmStructuredType structuredType)
        {
            if (Context.EnableNamingAlias)
            {
                typeName = Customization.CustomizeNaming(typeName);
            }

            // PropertyName in VB is case-insensitive.
            var isLanguageCaseSensitive = true;

            // In VB, it is allowed that a type has a property whose name is same with the type's name
            var allowPropertyNameSameWithTypeName = false;

            Func<string, string> customizePropertyName = name => { return Context.EnableNamingAlias ? Customization.CustomizeNaming(name) : name; };

            var propertyGroups = structuredType.Properties()
                .GroupBy(p => isLanguageCaseSensitive ? customizePropertyName(p.Name) : customizePropertyName(p.Name).ToUpperInvariant());

            // If the group contains more than one property, or the property in the group has the same name with the type (only for C#), we need to rename the property
            var propertyToBeRenamedGroups = propertyGroups.Where(g => g.Count() > 1 || !allowPropertyNameSameWithTypeName && g.Key == typeName);

            var knownIdentifiers = propertyGroups.Select(g => customizePropertyName(g.First().Name)).ToList();
            if (!allowPropertyNameSameWithTypeName && !knownIdentifiers.Contains(typeName))
            {
                knownIdentifiers.Add(typeName);
            }
            var uniqueIdentifierService =
                new UniqueIdentifierService(knownIdentifiers, isLanguageCaseSensitive);

            IdentifierMappings.Clear();
            foreach (var g in propertyToBeRenamedGroups)
            {
                var hasPropertyNameSameWithCustomizedPropertyName = false;
                var itemCount = g.Count();
                for (var i = 0; i < itemCount; i++)
                {
                    var property = g.ElementAt(i);
                    var customizedPropertyName = customizePropertyName(property.Name);

                    if (Context.EnableNamingAlias && customizedPropertyName == property.Name)
                    {
                        hasPropertyNameSameWithCustomizedPropertyName = true;
                    }

                    if (isLanguageCaseSensitive)
                    {
                        // If a property name is same as its customized property name, then we don't rename it.
                        // Or we don't rename the last property in the group
                        if (customizedPropertyName != typeName
                            && (customizedPropertyName == property.Name
                                || (!hasPropertyNameSameWithCustomizedPropertyName && i == itemCount - 1)))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        // When EnableNamingAlias = true, If a property name is same as its customized property name, then we don't rename it.
                        // Or we don't rename the last property in the group.
                        if ((Context.EnableNamingAlias && customizedPropertyName == property.Name)
                            || (!hasPropertyNameSameWithCustomizedPropertyName && i == itemCount - 1))
                        {
                            continue;
                        }
                    }
                    var renamedPropertyName = uniqueIdentifierService.GetUniqueIdentifier(customizedPropertyName);
                    IdentifierMappings.Add(property.Name, renamedPropertyName);
                }
            }
        }
        internal void WritePropertiesForStructuredType(IEnumerable<IEdmProperty> properties)
        {
            var useDataServiceCollection = Context.UseDataServiceCollection;

            var propertyInfos = properties.Select(property =>
            {
                var propertyName = IdentifierMappings.ContainsKey(property.Name) ?
                    IdentifierMappings[property.Name] : (Context.EnableNamingAlias ? Customization.CustomizeNaming(property.Name) : property.Name);

                return new
                {
                    PropertyType = Utils.GetClrTypeName(property.Type, useDataServiceCollection, this, Context),
                    PropertyVanillaName = property.Name,
                    PropertyName = propertyName,
                    FixedPropertyName = GetFixedName(propertyName),
                    PrivatePropertyName = "_" + propertyName,
                    PropertyInitializationValue = Utils.GetPropertyInitializationValue(property, useDataServiceCollection, this, Context)
                };
            }).ToList();

            // Private name should not confict with field name
            var uniqueIdentifierService = new UniqueIdentifierService(propertyInfos.Select(_ => _.FixedPropertyName), true);

            foreach (var propertyInfo in propertyInfos)
            {
                var privatePropertyName = uniqueIdentifierService.GetUniqueIdentifier("_" + propertyInfo.PropertyName);

                WritePropertyForStructuredType(
                    propertyInfo.PropertyType,
                    propertyInfo.PropertyVanillaName,
                    propertyInfo.PropertyName,
                    propertyInfo.FixedPropertyName,
                    privatePropertyName,
                    propertyInfo.PropertyInitializationValue,
                    useDataServiceCollection);
            }
        }