public void TestConnectorSerialization()
        {
            var obj = new SourceFieldList
                          {
                              Id = Guid.NewGuid(),
                          };
            obj.Fields.Add(new SourceField(null));
            obj.Fields.Add(new SourceField(null) { Subfields = { new SourceField(null) } });

            var tw = new StringWriter();
            using (var xw = XmlWriter.Create(tw))
            {
                xw.WriteStartElement("Node");
                obj.Serialize(xw);
                xw.WriteEndElement();
            }

            var sr = new StringReader(tw.ToString());
            using (var wr = XmlReader.Create(sr))
            {
                wr.ReadToFollowing("Node");
                var result = new SourceFieldList();
                result.Deserialize(wr);

                Assert.AreEqual(obj.Id, result.Id);
                Assert.AreEqual(obj.Fields.Count, result.Fields.Count);
            }
        }
        public void TestSourceFieldList_GetAllFields()
        {
            var obj = new SourceFieldList();
            obj.Fields.Add(new SourceField(null));
            obj.Fields.Add(new SourceField(null));
            obj.Fields[1].Subfields.Add(new SourceField(null));
            obj.Fields[1].Subfields.Add(new SourceField(null));
            obj.Fields[1].Subfields[1].Subfields.Add(new SourceField(null));
            obj.Fields[1].Subfields[1].Subfields.Add(new SourceField(null));

            Assert.AreEqual(6, obj.GetAllFields().Count());
        }
 /// <summary>
 /// Builds the source field for list.
 /// </summary>
 /// <param name="source">The source.</param>
 /// <param name="field">The field.</param>
 /// <param name="subfieldsRetriever">The subfields retriever.</param>
 /// <returns> Source Field. </returns>
 private static SourceField BuildSourceFieldForList(SourceFieldList source, FieldEdit field, IExpressionFieldsRetriever subfieldsRetriever)
 {
     return new SourceField(source)
         {
             DataType = NodeDataType.List,
             Name = field.Name,
             ConnectorOut = {DataType = NodeDataType.List, Name = field.Name},
             SetName = SourceFieldSetNames.Item,
             InnerName = string.Format("{0}List", field.SystemName),
             SystemName = string.Format("{0}List", field.SystemName),
             SubfieldsRetriever = subfieldsRetriever
         };
 }
        private static void AddLastModifiedOnField(ProcessEdit process, SourceFieldList source)
        {
            const string LastModifiedOnDisplyField = "Last Modified On";

            var dataType = SourceNodeFactory.GetDataType(typeof(DateTime));

            var sf = new SourceField(source)
            {
                DataType = dataType,
                Name = LastModifiedOnDisplyField,
                ConnectorOut = { DataType = dataType, Name = LastModifiedOnDisplyField },
                SetName = SourceFieldSetNames.Item,
                InnerName = Constants.LastModifiedOn,
                SystemName = Constants.LastModifiedOn
            };

            source.Fields.Add(sf);
        }
        /// <summary>
        /// Adds the version fields.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="source">The source.</param>
        private static void AddVersionFields(IProcessEdit process, SourceFieldList source)
        {
            const string VersionDateName = "Version Date";

            if (process.ProcessOptionChoose != ProcessOption.VersionEnabled)
                return;

            var dataType = SourceNodeFactory.GetDataType(typeof (string));

            var sf = new SourceField(source)
                         {
                             DataType = dataType,
                             Name = Constants.VersionNumberName,
                             ConnectorOut = { DataType = dataType, Name = Constants.VersionNumberName },
                             SetName = SourceFieldSetNames.Item,
                             InnerName = Constants.VersionNumber,
                             SystemName = Constants.VersionNumber
                         };

            source.Fields.Add(sf);

            dataType = SourceNodeFactory.GetDataType(typeof (DateTime));

            sf = new SourceField(source)
                     {
                         DataType = dataType,
                         Name = VersionDateName,
                         ConnectorOut = {DataType = dataType, Name = VersionDateName},
                         SetName = SourceFieldSetNames.Item,
                         InnerName = Constants.VersionDate,
                         SystemName = Constants.VersionDate
                     };

            source.Fields.Add(sf);

            dataType = SourceNodeFactory.GetDataType(typeof(int));

            sf = new SourceField(source)
            {
                DataType = dataType,
                Name = Constants.VersionMasterId,
                ConnectorOut = { DataType = dataType, Name = Constants.VersionMasterId },
                SetName = SourceFieldSetNames.Item,
                InnerName = Constants.VersionMasterId,
                SystemName = Constants.VersionMasterId,
            };

            source.Fields.Add(sf);
        }
        /// <summary>
        /// Adds the state fields.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="source">The source.</param>
        private static void AddStateFields(IProcessEdit process, SourceFieldList source)
        {
            const string CurrentStateName = "Current State";
            const string CurrentStateSystemName = "CurrentStateName";

            if (!process.IsStateEnabled)
                return;

            var dataType = SourceNodeFactory.GetDataType(typeof (string));

            var sf = new SourceField(source)
                         {
                             DataType = dataType,
                             Name = CurrentStateName,
                             ConnectorOut = {DataType = dataType, Name = CurrentStateName},
                             SetName = SourceFieldSetNames.Item,
                             InnerName = CurrentStateSystemName,
                             SystemName = CurrentStateSystemName
                         };

            source.Fields.Add(sf);
        }
        /// <summary>
        /// Adds the identifier fields.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="source">The source.</param>
        private static void AddIdFields(IProcessEdit process, SourceFieldList source)
        {
            const string IdName = "Id";
            const string BaseIdName = "Base Id";

            var dataType = SourceNodeFactory.GetDataType(typeof(int));
            var sf = new SourceField(source)
            {
                DataType = dataType,
                Name = IdName,
                ConnectorOut = { DataType = dataType, Name = IdName },
                SetName = SourceFieldSetNames.Item,
                InnerName = Constants.IdColumnName,
                SystemName = Constants.IdColumnName,
                ObjectName = "context"
            };
            source.Fields.Add(sf);

            if (process.BaseProcess != null)
            {
                sf = new SourceField(source)
                {
                    DataType = dataType,
                    Name = BaseIdName,
                    ConnectorOut = {DataType = dataType, Name = BaseIdName},
                    SetName = SourceFieldSetNames.Item,
                    InnerName = Constants.BaseIdColumnName,
                    SystemName = Constants.BaseIdColumnName,
                };
                source.Fields.Add(sf);
            }
        }
        /// <summary>
        /// Loads the expression items.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="syncProcess">The synchronize process.</param>
        private void LoadExpressionItems(ProcessEdit process, ESyncProcessEdit syncProcess)
        {
            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 = "Source", Top = 10, Left = 10 };

            foreach (var providerField in syncProcess.Endpoints.Source.ProviderFields)
            {
                var sourceField = CreateSourceField(providerField, source);

                if (sourceField != null)
                    source.Fields.Add(sourceField);
            }

            newExpressions.Add(source);

            var destination = new DestinationFieldList { ExpressionName = process.Name, Top = 10, Left = 600 };

            AddIdFields(destination);
            AddStateFields(process, destination);
            AddVersionFields(process, destination);

            foreach (var field in process.GetAllFields().Where(CanBeDestinationField))
            {
                var destinationField = CreateDestinationField(field, destination);

                if (destinationField != null)
                    destination.Fields.Add(destinationField);
            }

            newExpressions.Add(destination);

            if (!string.IsNullOrWhiteSpace(syncProcess.Map.Designer))
            {
                try
                {
                    var expressionsContainer = ExpressionsSerializer.Deserialize(syncProcess.Map.Designer);
                    ExpressionNodeFactory.RestoreConnections(expressionsContainer.Expressions);
                    expressions.AddRange(expressionsContainer.Expressions);
                }
                catch
                {
                    // Do nothing, new expressions will be used.
                }
            }

            UpdateStateList(process);

            UpdateStoredExpressions(expressions, newExpressions, syncContext);

            syncContext.OperationCompleted();
        }
        private SourceFieldList CreateSourceItem(
            ProcessInfo process,
            string uniqueName,
            string name,
            string objectName)
        {
            var source = new SourceFieldList { ExpressionName = name, UniqueName = uniqueName };

            AddIdFields(process, source, objectName, SourceFieldSetNames.DataTriggerSourceItem);
            AddStateFields(process, source, objectName, SourceFieldSetNames.DataTriggerSourceItem);
            AddVersionFields(process, source, objectName, SourceFieldSetNames.DataTriggerSourceItem);
            AddLastModifiedOnField(source, objectName, SourceFieldSetNames.DataTriggerSourceItem);

            foreach (var field in process.GetAllFields().Where(CanBeSourceField))
            {
                var sourceField = CreateSourceField(field, process.SystemName, source);
                sourceField.ObjectName = objectName;
                source.Fields.Add(sourceField);
            }

            return source;
        }
        /// <summary>
        /// Creates the source item.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <returns> The List of Source Field. </returns>
        private SourceFieldList CreateSourceItem(IProcessEdit process)
        {
            var result = new SourceFieldList { ExpressionName = process.Name, UniqueName = SourceItemName, Top = 10, Left = 10 };

            AddIdFields(process, result, SourceItemObjectName, SourceFieldSetNames.Item);
            AddProcessIdFields(process, result, SourceItemObjectName, SourceFieldSetNames.Item);
            AddStateFields(process, result, SourceItemObjectName, SourceFieldSetNames.Item);
            AddVersionFields(process, result, SourceItemObjectName, SourceFieldSetNames.Item);
            AddLastModifiedOnField(process, result, SourceItemObjectName, SourceFieldSetNames.Item);

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

            return result;
        }
        /// <summary>
        /// Creates the source item.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <returns>The List of Source Fields.</returns>
        private SourceFieldList CreateSourceItem(IEnumerable<ServiceMethodParameterEdit> parameters)
        {
            var result = new SourceFieldList { ExpressionName = "Source", UniqueName = SourceItemName, Top = 10, Left = 10 };

            foreach (var parameter in parameters.Where(CanBeSourceField))
                result.Fields.Add(CreateSourceField(parameter, result));

            return result;
        }
        private SourceFieldList CreateSourceItem(IProcessEdit process)
        {
            var result = new SourceFieldList { ExpressionName = process.Name, UniqueName = SourceItemName, Top = 10, Left = 10 };

            AddIdFields(process, result, string.Empty, SourceFieldSetNames.IntegrationServiceResultItem);
            AddStateFields(process, result, string.Empty, SourceFieldSetNames.IntegrationServiceResultItem);
            AddVersionFields(process, result, string.Empty, SourceFieldSetNames.IntegrationServiceResultItem);
            AddLastModifiedOnField(process, result, string.Empty, SourceFieldSetNames.IntegrationServiceResultItem);

            result.Fields.AddRange(process.GetAllFields().Where(CanBeSourceField).Select(field => CreateSourceField(field, result)));

            return result;
        }
        private SourceFieldList CreateSourceItem(
            string name,
            string uniqueName,
            int left,
            int top,
            IEnumerable<IWebServiceMethodParameterDescription> parameters,
            ICollection<IWebMethodCallResultField> resultFields)
        {
            var result = new SourceFieldList { ExpressionName = name, UniqueName = uniqueName, Top = top, Left = left };

            foreach (var parameter in parameters.Where(CanBeSourceField))
            {
                var resultField = resultFields.FirstOrDefault(f => f.Name == parameter.Name && string.IsNullOrEmpty(f.DeclaringTypeName));
                result.Fields.Add(CreateSourceField(parameter, resultField, result));
            }

            return result;
        }
        public void TestSourceFieldList_GetSourceFieldForConnection()
        {
            var obj = new SourceFieldList();
            obj.Fields.Add(new SourceField(null));
            obj.Fields.Add(new SourceField(null));
            obj.Fields[1].Subfields.Add(new SourceField(null));
            obj.Fields[1].Subfields.Add(new SourceField(null));
            obj.Fields[1].Subfields[1].Subfields.Add(new SourceField(null));
            obj.Fields[1].Subfields[1].Subfields.Add(new SourceField(null));

            Assert.AreEqual(obj.Fields[1].Subfields[1].Subfields[1].Id, obj.GetSourceFieldForConnection(obj.Fields[1].Subfields[1].Subfields[1].Connector).Id);
        }
        /// <summary>
        /// Edits the expression.
        /// </summary>
        /// <param name="parentWindow">The parent window.</param>
        /// <param name="process">The process.</param>
        /// <param name="expressionDesignerString">The expression designer string.</param>
        /// <param name="parameterType">Type of the parameter.</param>
        /// <param name="saveAction">The save action.</param>
        /// <param name="cancelAction">The cancel action.</param>
        /// <param name="removeAction">The remove action.</param>
        public void EditExpression(ITopLevelWindow parentWindow, ProcessEdit process, string expressionDesignerString, SystemParameterType parameterType, Action saveAction, Action cancelAction, Action removeAction)
        {
            this.saveAction = saveAction;
            this.cancelAction = cancelAction;
            this.removeAction = removeAction;
            
            var source = new SourceFieldList {ExpressionName = process.Name, Top = 10, Left = 10};

            AddIdFields(process, source);
            AddProcessIdFields(process, source);
            AddStateFields(process, source);
            AddVersionFields(process, source);
            AddLastModifiedOnField(process, source);


            foreach (var field in process.GetAllFields())
            {
                if (field.FieldType.ColumnType == ColumnTypes.Reference)
                {
                    var crossRefStep = (CrossRefRequiredStepEdit)field.StepList.FirstOrDefault(x => x is CrossRefRequiredStepEdit);
                    if (crossRefStep != null)
                    {
                        if (crossRefStep.AllowMultiple)
                        {
                            source.Fields.Add(BuildSourceFieldForList(source, field, new CrSubfieldsRetriever(field.Id)));
                        }
                        else
                        {
                            source.Fields.Add(new SourceField(source)
                            {
                                DataType = NodeDataType.CrossReference,
                                Name = field.Name,
                                ConnectorOut =
                                    {
                                        DataType = NodeDataType.CrossReference,
                                        Name = field.Name
                                    },
                                SetName = SourceFieldSetNames.Item,
                                InnerName = field.SystemName,
                                SystemName = string.Format("{0}Member", field.SystemName),
                                SubfieldsRetriever = new CrSubfieldsRetriever(field.Id)
                            });
                        }
                    }
                }
                else
                {
                    if (field.FieldType.ColumnType == ColumnTypes.ReverseReference || field.FieldType.ColumnType == ColumnTypes.ReverseMultiReference)
                    {
                        var crossRefStep = (ReverseCrossRefRequiredStepEdit)field.StepList.FirstOrDefault(x => x is ReverseCrossRefRequiredStepEdit);
                        if (crossRefStep != null)
                        {
                            if (crossRefStep.DisplayMultiple)
                            {
                                source.Fields.Add(BuildSourceFieldForList(source, field, new ReverseCrSubfieldsRetriever(field.Id)));
                            }
                            else
                            {
                                source.Fields.Add(new SourceField(source)
                                {
                                    DataType = NodeDataType.ReverseCrossReference,
                                    Name = field.Name,
                                    ConnectorOut =
                                    {
                                        DataType = NodeDataType.ReverseCrossReference,
                                        Name = field.Name
                                    },
                                    SetName = SourceFieldSetNames.Item,
                                    InnerName = field.SystemName,
                                    SystemName = string.Format("{0}Member", field.SystemName),
                                    SubfieldsRetriever = new ReverseCrSubfieldsRetriever(field.Id)
                                });
                            }
                        }
                    }
                    else if (field.FieldType.ColumnType == ColumnTypes.Checklist)
                    {
                        source.Fields.Add(BuildSourceFieldForList(source, field, new ChecklistSubFieldsRetriever(field.Id)));
                    }
                    else if (field.FieldType.ColumnType == ColumnTypes.DisplayList)
                    {
                        source.Fields.Add(BuildSourceFieldForList(source, field, new DisplayListSubFieldsRetriever(field.Id)));
                    }
                    else if (field.FieldType.ColumnType == ColumnTypes.Result)
                    {
                        source.Fields.Add(new SourceField(source)
                        {
                            DataType = NodeDataType.Result,
                            Name = field.Name,
                            ConnectorOut =
                            {
                                DataType = NodeDataType.Result,
                                Name = field.Name
                            },
                            SetName = SourceFieldSetNames.Item,
                            InnerName = field.SystemName,
                            SystemName = field.SystemName
                        });
                    }
                    else
                    {
                        //var fieldType = GetType(field.FieldType);
                        var dataType = SourceNodeFactory.GetDataType(GetType(field.FieldType));
                        var sf = new SourceField(source)
                                     {
                                         DataType = dataType,
                                         Name = field.Name,
                                         ConnectorOut = { DataType = dataType, Name = field.Name },
                                         SetName = SourceFieldSetNames.Item,
                                         InnerName = field.SystemName,
                                         SystemName = field.SystemName
                                     };
                        source.Fields.Add(sf);
                    }
                }
            }

            var expressions = new List<IExpressionObjectBase>();

            var isNew = true;

            ExpressionContainer expressionsContainer;
            try
            {
                expressionsContainer = Serializer.Deserialize(expressionDesignerString);
            }
            catch
            {
                expressionsContainer = null;
            }

            if (!string.IsNullOrWhiteSpace(expressionDesignerString) && expressionsContainer != null)
            {
                isNew = false;
                expressions.AddRange(expressionsContainer.Expressions);
            }
            else
            {
                expressions.Add(source);
                var destination = new DestinationFieldList
                                      {
                                          Top = 200,
                                          Left = 600,
                                          ExpressionName = "Expression Result"
                                      };
                destination.Fields.Add(new DestinationField(destination)
                                           {
                                               Name = "Result",
                                               SystemName = "Result",
                                               InnerName = "Result",
                                               DataType = GetNodeType(parameterType),
                                               ConnectorIn = { Name = "Result", DataType = GetNodeType(parameterType) }
                                           });
                expressions.Add(destination);
            }

            if (expressionsContainer != null)
            {
                var sourceFieldList =
                   (from fl in expressions
                    where fl is SourceFieldList
                    select fl).Cast<SourceFieldList>().FirstOrDefault();

                if (sourceFieldList != null)
                {
                    var fieldList = sourceFieldList.Fields.Cast<IExpressionField>().ToList();
                    UpdateStoredFields(fieldList, source.Fields, (sf) => FinalizeUpdate(sourceFieldList, fieldList, source, expressions, parentWindow)); // Here we load all subtypes async that's why we need reload window after all subtypes are loaded
                }
            }

            if (!isNew)
            {
                return;
            }

            var userInfoSource = SourceNodeFactory.CreateUserInformationItem(CurrentUserInformationItemName);
            userInfoSource.Left = 175;
            userInfoSource.Top = 10;

            expressions.Add(userInfoSource);

            this.expressionDesigner.Diagram.Items.Clear();
            ExpressionTranslator.TranslateToDiagram(expressions, this.expressionDesigner.Diagram);

            WindowManager.Value.ShowChildWindow(parentWindow, this);
        }
        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>
        /// Finalizes the update.
        /// </summary>
        /// <param name="sourceFieldList">The source field list.</param>
        /// <param name="fieldList">The field list.</param>
        /// <param name="source">The source.</param>
        /// <param name="expressions">The expressions.</param>
        /// <param name="parentWindow">The parent window.</param>
        private void FinalizeUpdate(SourceFieldList sourceFieldList, List<IExpressionField> fieldList, SourceFieldList source, List<IExpressionObjectBase> expressions, ITopLevelWindow parentWindow)
        {
            sourceFieldList.Fields.Clear();
            foreach (var field in fieldList)
            {
                sourceFieldList.Fields.Add((SourceField)field);
            }

            // delete obsolete fields (removed from process)
            var sourceListArray = sourceFieldList.Fields.ToArray();
            foreach (var field in sourceListArray)
            {
                if (source.Fields.All(t => t.Name != field.Name))
                {
                    var removed = sourceFieldList.Fields.First(t => t.Name == field.Name);
                    expressions.Remove(removed.ConnectorOut.Connection);

                    sourceFieldList.Fields.Remove(removed);
                }
            }

            this.expressionDesigner.LoadFromExpressionObjects(expressions);

            WindowManager.Value.ShowChildWindow(parentWindow, this);
        }
        /// <summary>
        /// To the source expression node.
        /// </summary>
        /// <param name="expressionObject">The expression object.</param>
        /// <param name="connection">The connection.</param>
        /// <returns>SourceFieldNode.</returns>
        /// <exception cref="Cebos.Veyron.Expressions.ExpressionCompiler.Exceptions.IncompleteTreeException"></exception>
        private SourceFieldNode ToSourceExpressionNode(SourceFieldList expressionObject, Connection connection)
        {
            if (!expressionObject.IsValid)
                throw new IncompleteTreeException(expressionObject);


            var field = expressionObject.GetSourceFieldForConnection(connection.Source);

            var fieldName = field.GetName();

            if (_values.ContainsKey(fieldName))
            {
                var value = _values[fieldName];
                return GetSourceExpressionNode(field, value);
            }

            return GetSourceExpressionNode(field, null);
        }