private ValidationRoot GetRootElement()
        {
            Activity rootElement = null;

            Fx.Assert(this.modelService != null, "ModelService is null."); // ModelService should not be null

            ModelItem rootItem = this.modelService.Root;
            object    root     = rootItem.GetCurrentValue();
            // special case for WorkflowService - it will be returned directly
            WorkflowService workflowService = root as WorkflowService;

            if (workflowService != null)
            {
                return(new ValidationRoot(workflowService));
            }
            //special case for ActivityBuilder - its will be converted to a DynamicActivity before validation.
            ActivityBuilder activityBuilder = root as ActivityBuilder;

            if (activityBuilder != null)
            {
                ActivityBuilderExtensions.ConvertActivityBuilderToDynamicActivity(activityBuilder, this.DynamicActivityWrapper);
                rootElement = this.DynamicActivityWrapper;
            }
            else
            {
                rootElement = rootItem.GetRootActivity();
            }

            IList <AssemblyReference> references;
            IList <string>            namespaces = NamespaceHelper.GetTextExpressionNamespaces(root, out references);

            NamespaceHelper.SetTextExpressionNamespaces(rootElement, namespaces, references);

            if (rootElement != null)
            {
                return(new ValidationRoot(rootElement));
            }
            else
            {
                return(null);
            }
        }
        private void OnValidationWorkCompleted(Tuple <ValidationReason, ValidationResults, Exception> input)
        {
            ValidationReason  reason    = input.Item1;
            ValidationResults results   = input.Item2;
            Exception         exception = input.Item3;

            Fx.Assert(results != null ^ exception != null, "result and exception should not both be null");

            bool needsToMarkValidationErrors        = false;
            ValidationErrorInfo validationErrorInfo = null;

            if (exception != null)
            {
                ModelItem rootModelItem = this.modelService.Root;
                Activity  rootActivity  = rootModelItem.GetRootActivity();

                if (rootActivity != null)
                {
                    // We don't want any crash propagating from here as it causes VS to crash.
                    if (!this.ValidationErrors.ContainsKey(rootActivity))
                    {
                        ValidationErrorState validationError = new ValidationErrorState(new List <string>(), ValidationState.Error);
                        this.ValidationErrors.Add(rootActivity, validationError);
                    }
                    else
                    {
                        this.ValidationErrors[rootActivity].ValidationState = ValidationState.Error;
                    }

                    this.ValidationErrors[rootActivity].ErrorMessages.Add(exception.ToString());

                    // Notify an update to the attached properties
                    this.NotifyValidationPropertiesChanged(rootModelItem);
                }

                validationErrorInfo         = new ValidationErrorInfo(exception.ToString());
                needsToMarkValidationErrors = true;
            }

            DesignerPerfEventProvider perfProvider = this.context.Services.GetService <DesignerPerfEventProvider>();

            perfProvider.WorkflowDesignerValidationStart();

            List <ValidationError> validationErrors = null;

            if (results != null)
            {
                validationErrors = new List <ValidationError>(results.Errors);
                validationErrors.AddRange(results.Warnings);
                Activity rootActivity = this.modelService.Root.GetRootActivity();
                needsToMarkValidationErrors = this.MarkErrors(validationErrors, reason, rootActivity);
            }

            if (this.errorService != null && needsToMarkValidationErrors) // Error service could be null if no implementation has been provided
            {
                List <ValidationErrorInfo> errors = new List <ValidationErrorInfo>();

                if (validationErrors != null)
                {
                    foreach (ValidationError validationError in validationErrors)
                    {
                        Activity            currentActivity = validationError.Source;
                        ValidationErrorInfo error           = new ValidationErrorInfo(validationError);

                        // The acquired activity reference will be release in the Main AppDomain when it clear the error list
                        if (validationError.SourceDetail != null)
                        {
                            error.SourceReferenceId = this.objectReferenceService.AcquireObjectReference(validationError.SourceDetail);
                        }
                        else if (validationError.Source != null)
                        {
                            error.SourceReferenceId = this.objectReferenceService.AcquireObjectReference(validationError.Source);
                        }
                        else
                        {
                            error.SourceReferenceId = Guid.Empty;
                        }
                        errors.Add(error);
                    }
                }

                if (validationErrorInfo != null)
                {
                    errors.Add(validationErrorInfo);
                }

                foreach (Guid acquiredObjectReference in this.AcquiredObjectReferences)
                {
                    this.objectReferenceService.ReleaseObjectReference(acquiredObjectReference);
                }

                this.AcquiredObjectReferences.Clear();

                foreach (ValidationErrorInfo error in errors)
                {
                    if (error.SourceReferenceId != Guid.Empty)
                    {
                        this.AcquiredObjectReferences.Add(error.SourceReferenceId);
                    }
                }

                this.errorService.ShowValidationErrors(errors);
            }

            perfProvider.WorkflowDesignerValidationEnd();
            this.OnValidationCompleted();
        }