private async void LoadExpressionItems(ProcessEdit sourceProcess, ExternalDataConfigurationEdit externalDataConfiguration, ProcessExternalDataEdit model)
        {
            WindowManager.Value.ShowStatus(new Status { IsBusy = true });

            var expressions = new List<IExpressionObjectBase>();
            var newExpressions = new List<IExpressionObjectBase>();

            var syncContext = new NotifyClientAction(
                () =>
                {
                    ExpressionDesigner.LoadFromExpressionObjects(expressions);
                    WindowManager.Value.ShowStatus(new Status());
                });

            syncContext.OperationStarted();

            var source = new SourceFieldList
                {
                    ExpressionName = string.Format("{0} (source)", sourceProcess.Name),
                    UniqueName = SourceItemName,
                    Top = 10,
                    Left = 10
                };

            foreach (var field in sourceProcess.GetAllFields().Where(CanBeSourceField))
            {
                var sourceField = CreateSourceField(field, source);
                sourceField.ObjectName = SourceItemObjectName;
                source.Fields.Add(sourceField);
            }
            
            newExpressions.Add(source);

            var modifiedSource = new SourceFieldList
            {
                ExpressionName = string.Format("External Data: {0}", externalDataConfiguration.Name),
                UniqueName = SourceToModifyItemName,
                Top = 310,
                Left = 10
            };

            // add data variable
            foreach (var field in externalDataConfiguration.DataVariableList)
            {
                var sourceField = CreateSourceFieldFromDataVariable(field, modifiedSource);
                sourceField.ObjectName = ModifiedItemObjectName;
                modifiedSource.Fields.Add(sourceField);
            }

            newExpressions.Add(modifiedSource);
          
            SourceFieldList systemParameters;

            try
            {
                systemParameters = await CreateSystemParametersItemAsync(SystemParametersName);
            }
            catch (Exception)
            {
                systemParameters = null;
            }

            if (systemParameters != null)
            {
                systemParameters.Left = 350;
                systemParameters.Top = 10;
                newExpressions.Add(systemParameters);
            }

            var destination = new DestinationFieldList
            {
                ExpressionName = sourceProcess.Name,
                UniqueName = DestinationItemName,
                Top = 10,
                Left = 500
            };

            foreach (var field in sourceProcess.GetAllFields().Where(CanBeDestinationField))
            {
                var destinationField = CreateDestinationField(field, destination);
                destination.Fields.Add(destinationField);
            }

            newExpressions.Add(destination);


            if (!string.IsNullOrWhiteSpace(model.Expression))
            {
                try
                {
                    var expressionsContainer = Serializer.Deserialize(model.Expression);
                    expressions.AddRange(expressionsContainer.Expressions);
                }
                catch
                {
                    // Do nothing, new expressions will be used.
                }
            }

            UpdateStoredExpressions(expressions, newExpressions, syncContext);
            syncContext.OperationCompleted();
        }
        /// <summary>
        /// Loads the expression items.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="dataSources">The data sources.</param>
        /// <param name="sourceDataProcess">The source data process.</param>
        /// <param name="destinationListField">The destination list field.</param>
        /// <param name="destinationProcess">The destination process.</param>
        /// <param name="fieldMapping">The field mapping.</param>
        private async void LoadExpressionItems(
            IProcessEdit process,
            IEnumerable<DataTriggerMappingDataSourceRetriever> dataSources,
            ProcessInfo sourceDataProcess,
            FieldInfo destinationListField,
            ProcessInfo destinationProcess,
            DataTriggerFieldMappingEdit fieldMapping)
        {
            WindowManager.Value.ShowStatus(new Status { IsBusy = true });

            var expressions = new List<IExpressionObjectBase>();
            var newExpressions = new List<IExpressionObjectBase>();

            var syncContext = new NotifyClientAction(
                () =>
                    {
                        ExpressionDesigner.LoadFromExpressionObjects(expressions);
                        WindowManager.Value.ShowStatus(new Status());
                    });

            syncContext.OperationStarted();

            if (fieldMapping.ModificationType == DataTriggerModificationType.Link || fieldMapping.ModificationType == DataTriggerModificationType.Unlink)
            {
                var objectName = string.Format("sourceData.GetSourceItem(\"{0}\")", DataTriggerFieldMappingExpressionNames.SourceDataProcess);

                newExpressions.Add(CreateSourceItem(sourceDataProcess, DataTriggerFieldMappingExpressionNames.SourceDataProcess, sourceDataProcess.Name, objectName));
            }
            else
            {
                foreach (var dataSource in dataSources)
                {
                    var name = string.Format(CultureInfo.InvariantCulture, "{0} (source)", dataSource.SourceFieldName);
                    var objectName = string.Format("sourceData.GetSourceItem(\"{0}\")", dataSource.SourceName);
                    newExpressions.Add(CreateSourceItem(dataSource.SourceProcess, dataSource.SourceName, name, objectName));
                }

                newExpressions.Add(
                    CreateSourceItem(
                        destinationProcess,
                        DataTriggerFieldMappingExpressionNames.ModifiedItem,
                        string.Format("{0} (old)", destinationListField.Name),
                        ModifiedItemObjectName));
            }

            newExpressions.Add(CreateUserInfoSourceItem(DataTriggerFieldMappingExpressionNames.UserInfo));

            try
            {
                var systemParameters = await CreateSystemParametersItemAsync(DataTriggerFieldMappingExpressionNames.SystemParameters);
                if (systemParameters != null)
                {
                    newExpressions.Add(systemParameters);
                }
            }
            catch (DataPortalException)
            {
            }

            newExpressions.Add(CreateDestinationItem(destinationProcess, DataTriggerFieldMappingExpressionNames.DestinationItem, destinationListField.Name));

            UpdatePositions(newExpressions);

            if (!string.IsNullOrWhiteSpace(fieldMapping.Expression))
            {
                try
                {
                    var expressionsContainer = Serializer.Deserialize(fieldMapping.Expression);
                    expressions.AddRange(expressionsContainer.Expressions);
                }
                catch
                {
                    // Do nothing, new expressions will be used.
                }
            }

            UpdateStateList(process);

            UpdateStoredExpressions(expressions, newExpressions, syncContext);
            syncContext.OperationCompleted();
        }
        /// <summary>
        /// Initiates expression editing.
        /// </summary>
        /// <param name="parentWindow">The parent window.</param>
        /// <param name="process">The process containing rule.</param>
        /// <param name="rule">The rule containing expression.</param>
        /// <param name="saveAction">The save action.</param>
        /// <param name="cancelAction">The cancel action.</param>
        /// <param name="removeAction">The remove action.</param>
        public async void EditExpression(
            ITopLevelWindow parentWindow,
            IProcessEdit process,
            ProcessActionRuleEdit rule,
            Action saveAction,
            Action cancelAction,
            Action removeAction)
        {
            WindowManager.Value.ShowStatus(new Status { IsBusy = true });

            SaveAction = saveAction;
            CancelAction = cancelAction;
            RemoveAction = removeAction;

            ProcessEdit = process;

            ExpressionDesigner.LoadFromExpressionObjects(new List<IExpressionObjectBase>());

            var expressions = new List<IExpressionObjectBase>();
            var newExpressions = new List<IExpressionObjectBase>();

            var syncContext = new NotifyClientAction(
                () =>
                {
                    ExpressionDesigner.LoadFromExpressionObjects(expressions);
                    WindowManager.Value.ShowStatus(new Status());

                    _itemHashes = ExpressionDesigner.Diagram.Items.Select(x => x.GetHashCode()).ToList();
                });

            syncContext.OperationStarted();

            var oldSourceName = string.Format("Old {0}", process.SystemName);
            var sourceName = process.SystemName;

            newExpressions.Add(CreateSourceItem(process, oldSourceName, OldSourceItemName, OldItemObjectName, 10, 10));
            newExpressions.Add(CreateSourceItem(process, sourceName, NewSourceItemName, NewItemObjectName, 10, 300));
            newExpressions.Add(CreateUserInfoSourceItem());
            newExpressions.Add(CreateDestinationItem());

            SourceFieldList systemParameters;

            try
            {
                systemParameters = await CreateSystemParametersItemAsync(SystemParametersItemName);
            }
            catch (Exception)
            {
                systemParameters = null;
            }

            if (systemParameters != null)
                newExpressions.Add(systemParameters);

            if (!string.IsNullOrWhiteSpace(rule.Expression))
            {
                try
                {
                    var expressionsContainer = Serializer.Deserialize(rule.Expression);
                    expressions.AddRange(expressionsContainer.Expressions);
                }
                catch
                {
                    // Do nothing, new expressions will be used.
                }
            }
            
            UpdateStateList(process);

            UpdateStoredExpressions(expressions, newExpressions, syncContext);
            syncContext.OperationCompleted();

            WindowManager.Value.ShowChildWindow(parentWindow, this);
        }
        /// <summary>
        /// Loads the expression items.
        /// </summary>
        /// <param name="sourceProcess">The source process.</param>
        /// <param name="destinationProcess">The destination process.</param>
        /// <param name="trigger">The trigger.</param>
        private async void LoadExpressionItems(
            IProcessEdit sourceProcess,
            ProcessInfo destinationProcess,
            ProcessDataTriggerEdit trigger)
        {
            WindowManager.Value.ShowStatus(new Status { IsBusy = true });

            var expressions = new List<IExpressionObjectBase>();
            var newExpressions = new List<IExpressionObjectBase>();

            var syncContext = new NotifyClientAction(
                () =>
                    {
                        ExpressionDesigner.LoadFromExpressionObjects(expressions);
                        IsSaveable = IsTestable();
                        WindowManager.Value.ShowStatus(new Status());
                    });

            syncContext.OperationStarted();

            newExpressions.Add(
                CreateSourceItem(
                    sourceProcess,
                    DataTriggerMappingExpressionNames.SourceItem,
                    string.Format("{0} (source)", sourceProcess.Name),
                    SourceItemObjectName));

            if (trigger.ModificationType != DataTriggerModificationType.Self)
                newExpressions.Add(
                    CreateSourceItem(
                        destinationProcess,
                        DataTriggerMappingExpressionNames.SourceToModifyItem,
                        string.Format("{0} (old)", destinationProcess.Name),
                        ModifiedItemObjectName));

            newExpressions.Add(CreateUserInfoSourceItem(DataTriggerMappingExpressionNames.UserInfo));

            try
            {
                var systemParameters = await CreateSystemParametersItemAsync(DataTriggerMappingExpressionNames.SystemParameters);
                if (systemParameters != null)
                {
                    newExpressions.Add(systemParameters);
                }
            }
            catch (DataPortalException)
            {
            }

            newExpressions.Add(CreateDestinationItem(destinationProcess, DataTriggerMappingExpressionNames.DestinationItem, destinationProcess.Name));

            UpdatePositions(newExpressions);

            if (!string.IsNullOrWhiteSpace(trigger.ModificationMapping))
            {
                try
                {
                    var expressionsContainer = Serializer.Deserialize(trigger.ModificationMapping);
                    expressions.AddRange(expressionsContainer.Expressions);
                }
                catch
                {
                    // Do nothing, new expressions will be used.
                }
            }

            UpdateStateList(sourceProcess);

            UpdateStoredExpressions(expressions, newExpressions, syncContext);
            syncContext.OperationCompleted();
        }