/// <summary>
        /// Adds the editable root on child changed method body.
        /// </summary>
        /// <param name="assemblyCode">The assembly code.</param>
        /// <param name="process">The process.</param>
        protected override void AddEditableRootOnChildChangedMethodBody(StringBuilder assemblyCode, IProcessDefinition process)
        {
            base.AddEditableRootOnChildChangedMethodBody(assemblyCode, process);

            var listFieldsUsedInExpressions = new Dictionary<string, HashSet<string>>();
            
            foreach (var field in process.RootTable.FieldList.Where(f => !f.AllowLocalizedData))
            {
                if (field.IsCalculated)
                {
                    var sourceFields = new HashSet<string>(ExpressionService.GetExpressionSourceFields(field.CalculatedExpression));
                    if (sourceFields.Count > 0)
                    {
                        assemblyCode.AppendFormat(@"
            if (Has{0}Changed(e))
            {{
                UpdateCalculatedProperty({0}Property, {0}Expression);
            }}

            ", field.SystemName);

                        var multiRefFields =
                            process.RootTable.FieldList.Where(
                                f =>
                                (f.ColumnType == ColumnTypes.MultiReference ||
                                 f.ColumnType == ColumnTypes.ReverseMultiReference ||
                                 f.ColumnType == ColumnTypes.Checklist ||
                                 f.ColumnType == ColumnTypes.DisplayList ||
                                 f.ColumnType == ColumnTypes.Sample) && sourceFields.Contains(f.SystemName + "List"));

                        foreach (var calculatedFields in multiRefFields.Select(multirefField => listFieldsUsedInExpressions.ContainsKey(multirefField.SystemName)
                                                                                                    ? listFieldsUsedInExpressions[multirefField.SystemName]
                                                                                                    : (listFieldsUsedInExpressions[multirefField.SystemName] = new HashSet<string>())))
                            calculatedFields.Add(field.SystemName);
                    }
                }
                else if (field.HasDefaultExpression)
                {
                    var sourceFields = new HashSet<string>(ExpressionService.GetExpressionSourceFields(field.DefaultValueExpression, true));

                    if (sourceFields.Count > 0)
                    {
                        assemblyCode.AppendFormat(@"
            if (this.IsNew && Has{0}Changed(e))
            {{
                UpdateCalculatedProperty({0}Property, {0}Expression);
            }}
            ", field.SystemName);
                    }
                }

                // add crossrefs filters
                if (field.ColumnType == ColumnTypes.Reference)
                {
                    // check if we have a filter
                    var filterFields = GetCrossRefFilterFields(field);
                    if (filterFields == null || filterFields.Length == 0)
                        continue;

                    assemblyCode.AppendFormat(
                        @"
            if (e.ChildObject is IDynamicObject && this.IsAncestorOf((IDynamicObject)e.ChildObject))
            {{
            ");

                    foreach (var filterField in filterFields)
                    {
                        var filterFieldProcessName = process.GetProcessNameByFieldName(filterField);

                        if (!string.IsNullOrWhiteSpace(filterFieldProcessName))
                            assemblyCode.AppendFormat(
                                @"
                if (e.PropertyChangedArgs.PropertyName == ""{0}"")
                {{
                    LoadProperty({1}Property, Constants.ReloadCRListValue);
                    RaisePropertyChanged(""{1}"");
                }}
",
                                filterField,
                                field.SystemName);
                    }

                    assemblyCode.AppendFormat(@"
            }}
                ");
                }                

                // add Display List filters
                if (field.ColumnType == ColumnTypes.DisplayList)
                {
                    // check if we have a filter
                    var filterFields = GetCrossRefFilterFields(field);
                    if (filterFields == null || filterFields.Length == 0)
                        continue;

                    assemblyCode.AppendFormat(
                        @" if (e.ChildObject is IDynamicObject && this.IsAncestorOf((IDynamicObject)e.ChildObject))
                            {{");

                    foreach (var filterField in filterFields)
                    {
                        var filterFieldProcessName = process.GetProcessNameByFieldName(filterField);

                        if (!string.IsNullOrWhiteSpace(filterFieldProcessName))
                            assemblyCode.AppendFormat(
                                @"
                if (e.PropertyChangedArgs.PropertyName == ""{0}"")
                {{                    
                    {1} = null;                    
                }}
",
                                filterField,
                                field.SystemName);
                    }

                    assemblyCode.Append(@"
            }
                ");
                }
            }

            foreach (var listField in listFieldsUsedInExpressions)
            {
                var field = process.RootTable.FieldList.FirstOrDefault(f => f.SystemName == listField.Key);
                //ELMTSUP-253
                var listHandlerString = field != null && (field.ColumnType == ColumnTypes.DisplayList || field.ColumnType == ColumnTypes.MultiReference)
                    ? string.Format("Load{0}List();", listField.Key)
                    : string.Format("{0}List = null;", listField.Key);

                assemblyCode.AppendFormat(
                    @"
                if (e.ChildObject == this.GetValueByPropertyName(""{0}""))
                {{
                    {1}
", listField.Key, listHandlerString);

                // reset list items if Enumerable field changed
                foreach (var calcField in listField.Value)
                    assemblyCode.AppendFormat(
                        @"
                    UpdateCalculatedProperty({0}Property, {0}Expression);
", calcField);

                assemblyCode.Append(
                    @"
                }
");
            }
        }
        /// <summary>
        /// Adds the editable root on property changed method body.
        /// </summary>
        /// <param name="assemblyCode">The assembly code.</param>
        /// <param name="process">The process.</param>
        protected override void AddEditableRootOnPropertyChangedMethodBody(StringBuilder assemblyCode, IProcessDefinition process)
        {
            base.AddEditableRootOnPropertyChangedMethodBody(assemblyCode, process);

            foreach (var field in process.RootTable.FieldList.Where(f => !f.AllowLocalizedData))
            {
                if (field.ColumnType == ColumnTypes.DisplayList)
                {
                    // check if we have a filter
                    var filterFields = GetCrossRefFilterFields(field);
                    if (filterFields == null || filterFields.Length == 0)
                        continue;

                    foreach (var filterField in filterFields)
                    {
                        var filterFieldProcessName = process.GetProcessNameByFieldName(filterField);

                        if (!string.IsNullOrWhiteSpace(filterFieldProcessName))
                            assemblyCode.AppendFormat(@"           
                if(propertyName == ""{0}"")
                {{               
                    {1} = null;
                }}", filterField, field.SystemName);
                    }
                }

                if (field.ColumnType == ColumnTypes.Reference)
                {
                    // check if we have a filter
                    var filterFields = GetCrossRefFilterFields(field);
                    if (filterFields.Any())
                    {
                        foreach (var filterField in filterFields)
                        {
                            var filterFieldProcessName = process.GetProcessNameByFieldName(filterField);

                            //                            if (!string.IsNullOrWhiteSpace(filterFieldProcessName))
                            //                                assemblyCode.AppendFormat(@"           
                            //                if(propertyName == ""{0}"")
                            //                {{               
                            //                    LoadProperty({1}Property, Constants.ReloadCRListValue);
                            //                    RaisePropertyChanged(""{1}"");
                            //                }}", filterField, field.SystemName);
                            if (!string.IsNullOrWhiteSpace(filterFieldProcessName))
                                assemblyCode.AppendFormat(@"           
                if(propertyName == ""{0}"")
                {{               
                    base.PropertyHasChanged({1}CrossRefFilterProperty);                    
 
                }}", filterField, field.SystemName);


                        }
                    }
                }

                if (field.IsCalculated)
                {
                    var sourceFields = new HashSet<string>(ExpressionService.GetExpressionSourceFields(field.CalculatedExpression, true));

                    if (sourceFields.Count > 0)
                    {
                        assemblyCode.AppendFormat(@"
            if (Has{0}Changed(propertyName))
            {{
                UpdateCalculatedProperty({0}Property, {0}Expression);
            }}
            ", field.SystemName);

                        var multiRefFields =
                            process.RootTable.FieldList.Where(
                                f =>
                                (f.ColumnType == ColumnTypes.MultiReference || f.ColumnType == ColumnTypes.ReverseMultiReference
                                 || f.ColumnType == ColumnTypes.Checklist || f.ColumnType == ColumnTypes.DisplayList)
                                && sourceFields.Contains(f.SystemName + "List"));

                        var listFieldsUsedInExpressions = new Dictionary<string, HashSet<string>>();

                        foreach (var calculatedFields in
                            multiRefFields.Select(
                                multirefField =>
                                listFieldsUsedInExpressions.ContainsKey(multirefField.SystemName)
                                    ? listFieldsUsedInExpressions[multirefField.SystemName]
                                    : (listFieldsUsedInExpressions[multirefField.SystemName] = new HashSet<string>())))
                            calculatedFields.Add(field.SystemName);

                        foreach (var listField in listFieldsUsedInExpressions)
                        {
                            var fieldList = process.RootTable.FieldList.FirstOrDefault(f => f.SystemName == listField.Key);
                            //ELMTSUP-253
                            var listHandlerString = fieldList != null
                                                    && (fieldList.ColumnType == ColumnTypes.DisplayList || fieldList.ColumnType == ColumnTypes.MultiReference)
                                                        ? string.Format("Load{0}List();", listField.Key)
                                                        : string.Format("{0}List = null;", listField.Key);

                            assemblyCode.AppendFormat(@"
                                    if (propertyName == ""{0}"")
                                    {{
                    {1}
", listField.Key, listHandlerString);

                            // reset list items if Enumerable field changed
                            foreach (var calcField in listField.Value)
                            {
                                assemblyCode.AppendFormat(@"
                                        UpdateCalculatedProperty({0}Property, {0}Expression);
                    ", calcField);
                            }

                            assemblyCode.Append(@"
                                    }
                    ");
                        }
                    }
                }
                else if (field.HasDefaultExpression)
                {
                    var sourceFields = new HashSet<string>(ExpressionService.GetExpressionSourceFields(field.DefaultValueExpression, true));

                    if (sourceFields.Count > 0)
                    {
                        assemblyCode.AppendFormat(@"
                if (this.IsNew && Has{0}Changed(propertyName))
                {{
                    UpdateCalculatedProperty({0}Property, {0}Expression);
                }}
            ", field.SystemName);

                        // Start of ELMTSUP-2366 fix
                        var multiRefFields =
                            process.RootTable.FieldList.Where(
                                f =>
                                (f.ColumnType == ColumnTypes.MultiReference || f.ColumnType == ColumnTypes.ReverseMultiReference
                                 || f.ColumnType == ColumnTypes.Checklist || f.ColumnType == ColumnTypes.DisplayList)
                                && sourceFields.Contains(f.SystemName + "List"));

                        var listFieldsUsedInExpressions = new Dictionary<string, HashSet<string>>();

                        foreach (var calculatedFields in
                            multiRefFields.Select(
                                multirefField =>
                                listFieldsUsedInExpressions.ContainsKey(multirefField.SystemName)
                                    ? listFieldsUsedInExpressions[multirefField.SystemName]
                                    : (listFieldsUsedInExpressions[multirefField.SystemName] = new HashSet<string>())))
                            calculatedFields.Add(field.SystemName);

                        foreach (var listField in listFieldsUsedInExpressions)
                        {
                            var fieldList = process.RootTable.FieldList.FirstOrDefault(f => f.SystemName == listField.Key);
                            
                            var listHandlerString = fieldList != null
                                                    && (fieldList.ColumnType == ColumnTypes.DisplayList || fieldList.ColumnType == ColumnTypes.MultiReference)
                                                        ? string.Format("Load{0}List();", listField.Key)
                                                        : string.Format("{0}List = null;", listField.Key);

                            assemblyCode.AppendFormat(@"
                                    if (propertyName == ""{0}"")
                                    {{
                    {1}
", listField.Key, listHandlerString);
                            
                            assemblyCode.Append(@"
                                    }
                    ");
                        }
                        // End of ELMTSUP-2366 fix
                    }
                }

                if (field.ColumnType == ColumnTypes.Result)
                {
                    assemblyCode.AppendFormat(@"
            if (propertyName.ToLowerInvariant().Equals(""{0}""))
                {1}{2}();
                    ", field.ReferencedColumnName.ToLowerInvariant(), field.SystemName, Constants.ResultListSetMethodPostfix);
                }
            }
        }