private void CreateContentTypes(Dictionary <string, ContentType> parentTypes)
        {
            var i = 0;

            var sortedCreators = new List <KeyValuePair <string, ContentTypeCreator> >();

            var missingIds = false;

            foreach (var c in Creators.Values)
            {
                if (c.Id == null)
                {
                    missingIds = true;
                }
            }

            var sortingCreators = Creators.ToList();

            //Microsoft.SharePoint.Client.ServerException: parameters.Id, parameters.ParentContentType cannot be used together. Please only use one of them.
            if (_ctx.ServerVersion >= Version.Parse("15.0.4569.1509") && !missingIds)
            {
                //By definition, sorting by the content type ID puts the parents before the childres
                sortingCreators.Sort((p1, p2) => string.Compare(p1.Value.Id, p2.Value.Id, StringComparison.Ordinal));
                sortedCreators = sortingCreators;
            }
            else
            {
                foreach (var c in sortingCreators)
                {
                    if (!sortedCreators.Contains(c))
                    {
                        sortedCreators.Add(c);
                    }
                    if (c.Value.ParentContentTypeName != null && Creators.Keys.Contains(c.Value.ParentContentTypeName))
                    {
                        var parentKvp = new KeyValuePair <string, ContentTypeCreator>(c.Value.ParentContentTypeName,
                                                                                      Creators[c.Value.ParentContentTypeName]);
                        if (!sortedCreators.Contains(parentKvp))
                        {
                            sortedCreators.Insert(sortedCreators.IndexOf(c), parentKvp);
                        }
                    }
                }
            }

            //Create the new types
            foreach (var creator in sortedCreators)
            {
                if (!_existingContentTypes.Keys.Contains(creator.Key))
                {
                    i++;
                    var typeInfo = new ContentTypeCreationInformation {
                        Name = creator.Key
                    };

                    //Microsoft.SharePoint.Client.ServerException: parameters.Id, parameters.ParentContentType cannot be used together. Please only use one of them.
                    if (!string.IsNullOrEmpty(creator.Value.Id) && _ctx.ServerVersion >= Version.Parse("15.0.4569.1509"))
                    {
                        typeInfo.Id = creator.Value.Id;
                    }
                    else
                    {
                        typeInfo.ParentContentType = parentTypes[creator.Value.ParentContentTypeName];

                        //If the parent type didn't exist before, it might now in one of the creators
                        //TODO: Once it's all SP1 CSOM this won't be needed. Always use the ID.
                        if (typeInfo.ParentContentType == null &&
                            Creators.Keys.Contains(creator.Value.ParentContentTypeName) &&
                            Creators[creator.Value.ParentContentTypeName].ContentType != null)
                        {
                            typeInfo.ParentContentType = Creators[creator.Value.ParentContentTypeName].ContentType;
                        }
                    }

                    typeInfo.Description = creator.Value.Description;
                    typeInfo.Group       = creator.Value.Group;

                    //Always create in root web
                    Creators[creator.Key].ContentType = _targetWeb.ContentTypes.Add(typeInfo);
                    _ctx.Load(Creators[creator.Key].ContentType, c => c.Name, c => c.FieldLinks);

                    OnNotify(ProvisioningNotificationLevels.Verbose, "Creating content type " + creator.Key);

                    //Workaround for 'The request uses too many resources bug', do 5 at a time
                    if (i % 5 == 0)
                    {
                        _ctx.ExecuteQueryRetry();
                    }
                }
                else
                {
                    OnNotify(ProvisioningNotificationLevels.Verbose,
                             "Creating content " + creator.Key + " already exists. Skipping creation");
                    creator.Value.ContentType = _existingContentTypes[creator.Key];
                }
                _createdContentTypes.Add(creator.Key);
            }
            _ctx.ExecuteQueryRetry();
        }