private void SharePointOnlineWait(TermGroupModelHost groupModelHost, TaxonomyTermSetDefinition termSetModel)
        {
            // wait until the group is there
            // Nested terms provisioning in Office 365 fails #995
            // TermSet not found #994
            var context = groupModelHost.HostClientContext;

            if (IsSharePointOnlineContext(context))
            {
                var currentTermSet = FindTermSet(groupModelHost.HostGroup, termSetModel);

                if (currentTermSet == null)
                {
                    TryRetryService.TryWithRetry(() =>
                    {
                        currentTermSet = FindTermSet(groupModelHost.HostGroup, termSetModel);
                        return(currentTermSet != null);
                    });
                }

                if (currentTermSet == null)
                {
                    throw new SPMeta2Exception(string.Format("Cannot find a termset after provision"));
                }
            }
        }
        private void DeployTaxonomyTermSet(object modelHost, TermGroupModelHost groupModelHost, TaxonomyTermSetDefinition termSetModel)
        {
            var termStore = groupModelHost.HostTermStore;
            var termGroup = groupModelHost.HostGroup;

            var currentTermSet = FindTermSet(termGroup, termSetModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentTermSet,
                ObjectType       = typeof(TermSet),
                ObjectDefinition = termSetModel,
                ModelHost        = modelHost
            });

            if (currentTermSet == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new Term Set");

                currentTermSet = termSetModel.Id.HasValue
                    ? termGroup.CreateTermSet(termSetModel.Name, termSetModel.Id.Value, termSetModel.LCID)
                    : termGroup.CreateTermSet(termSetModel.Name, Guid.NewGuid(), termSetModel.LCID);

                MapTermSet(currentTermSet, termSetModel);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentTermSet,
                    ObjectType       = typeof(TermSet),
                    ObjectDefinition = termSetModel,
                    ModelHost        = modelHost
                });
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing Term Set");

                MapTermSet(currentTermSet, termSetModel);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentTermSet,
                    ObjectType       = typeof(TermSet),
                    ObjectDefinition = termSetModel,
                    ModelHost        = modelHost
                });
            }

            termStore.CommitAll();
            termStore.Context.ExecuteQueryWithTrace();
        }
        private void DeployTaxonomyTermSet(object modelHost, TermGroupModelHost groupModelHost, TaxonomyTermSetDefinition termSetModel)
        {
            var termStore = groupModelHost.HostTermStore;
            var termGroup = groupModelHost.HostGroup;

            var currentTermSet = FindTermSet(termGroup, termSetModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentTermSet,
                ObjectType       = typeof(TermSet),
                ObjectDefinition = termSetModel,
                ModelHost        = modelHost
            });

            if (currentTermSet == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new Term Set");

                currentTermSet = termSetModel.Id.HasValue
                    ? termGroup.CreateTermSet(termSetModel.Name, termSetModel.Id.Value, termSetModel.LCID)
                    : termGroup.CreateTermSet(termSetModel.Name, Guid.NewGuid(), termSetModel.LCID);

                MapTermSet(currentTermSet, termSetModel);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentTermSet,
                    ObjectType       = typeof(TermSet),
                    ObjectDefinition = termSetModel,
                    ModelHost        = modelHost
                });
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing Term Set");

                UpdateExistingTaxonomyTermSet(modelHost, termSetModel, currentTermSet);
            }

            termStore.CommitAll();

            try
            {
                termStore.Context.ExecuteQueryWithTrace();
            }
            catch (Exception e)
            {
                var context = groupModelHost.HostClientContext;

                if (!IsSharePointOnlineContext(context))
                {
                    throw;
                }

                // SPMeta2 Provisioning Taxonomy Group with CSOM Standard #959
                // https://github.com/SubPointSolutions/spmeta2/issues/959

                // seems that newly created group might not be available for the time being
                // handling that "Group names must be unique." exception
                // trying to find the group and only update description
                var serverException = e as ServerException;

                if (serverException != null &&
                    serverException.ServerErrorCode == -2146233088)
                {
                    currentTermSet = FindTermSet(termGroup, termSetModel);

                    if (currentTermSet == null)
                    {
                        TryRetryService.TryWithRetry(() =>
                        {
                            currentTermSet = FindTermSet(termGroup, termSetModel);
                            return(currentTermSet != null);
                        });
                    }

                    UpdateExistingTaxonomyTermSet(modelHost, termSetModel, currentTermSet);

                    termStore.CommitAll();
                    termStore.RefreshLoad();

                    termStore.Context.ExecuteQueryWithTrace();
                }
            }

            groupModelHost.ShouldUpdateHost = false;
        }