private async Task <string> TrasnferWorkflowsStates()
        {
            StringBuilder content = new StringBuilder();

            await _comparerSource.InitializeConnection(_iWriteToOutput, content, "Connection CRM Source.", "Connection CRM Target.");

            string operation = string.Format(Properties.OperationNames.TransferingWorkflowsStatesFormat2, ConnectionSource.Name, ConnectionTarget.Name);

            content.AppendLine(_iWriteToOutput.WriteToOutputStartOperation(null, operation));

            var columnsSet = new ColumnSet
                             (
                Workflow.Schema.EntityPrimaryIdAttribute
                , Workflow.Schema.Attributes.primaryentity
                , Workflow.Schema.Attributes.category
                , Workflow.Schema.Attributes.name
                , Workflow.Schema.Attributes.statecode
                , Workflow.Schema.Attributes.statuscode
                , Workflow.Schema.Attributes.iscrmuiworkflow
                , Workflow.Schema.Attributes.ismanaged
                             );

            var taskSource = _comparerSource.GetWorkflow1Async(columnsSet);
            var taskTarget = _comparerSource.GetWorkflow2Async(columnsSet);

            List <Workflow> listSource = (await taskSource).ToList();

            content.AppendLine(_iWriteToOutput.WriteToOutput(null, Properties.OrganizationComparerStrings.WorkflowsInConnectionFormat2, ConnectionSource.Name, listSource.Count()));

            List <Workflow> listTarget = (await taskTarget).ToList();

            content.AppendLine(_iWriteToOutput.WriteToOutput(null, Properties.OrganizationComparerStrings.WorkflowsInConnectionFormat2, ConnectionTarget.Name, listTarget.Count()));

            List <LinkedEntities <Workflow> > commonList = new List <LinkedEntities <Workflow> >();

            foreach (Workflow workflowSource in listSource)
            {
                Workflow workflowTarget = listTarget.FirstOrDefault(workflow => workflow.Id == workflowSource.Id);

                if (workflowTarget != null)
                {
                    commonList.Add(new LinkedEntities <Workflow>(workflowSource, workflowTarget));
                    continue;
                }
            }

            content.AppendLine(_iWriteToOutput.WriteToOutput(null, Properties.OrganizationComparerStrings.WorkflowsCommonFormat3, ConnectionSource.Name, ConnectionTarget.Name, commonList.Count()));

            List <Workflow> workflowsToActivate   = new List <Workflow>();
            List <Workflow> workflowsToDeactivate = new List <Workflow>();

            {
                ProgressReporter reporter = new ProgressReporter(_iWriteToOutput, commonList.Count, 5, Properties.OrganizationComparerStrings.WorkflowsProcessingCommon);

                foreach (LinkedEntities <Workflow> workflow in commonList)
                {
                    reporter.Increase();

                    if (workflow.Entity1.StatusCode?.Value != workflow.Entity2.StatusCode?.Value)
                    {
                        List <Workflow> list = null;

                        if (workflow.Entity1.StatusCode.Value == (int)Workflow.Schema.OptionSets.statuscode.Activated_1_Activated_2)
                        {
                            list = workflowsToActivate;
                        }
                        else if (workflow.Entity1.StatusCode.Value == (int)Workflow.Schema.OptionSets.statuscode.Draft_0_Draft_1)
                        {
                            list = workflowsToDeactivate;
                        }

                        if (list != null)
                        {
                            list.Add(workflow.Entity2);
                        }
                    }
                }
            }

            var orderedDeactivate = workflowsToDeactivate
                                    .OrderBy(w => w.PrimaryEntity)
                                    .ThenBy(w => w.Category?.Value)
                                    .ThenBy(w => w.Name)
                                    .ThenBy(w => w.Id);

            var orderedActivate = workflowsToActivate
                                  .OrderBy(w => w.PrimaryEntity)
                                  .ThenBy(w => w.Category?.Value)
                                  .ThenBy(w => w.Name)
                                  .ThenBy(w => w.Id);

            FormatTextTableHandler tableDeactivateWorkflows = new FormatTextTableHandler();

            tableDeactivateWorkflows.SetHeader("Entity", "Category", "Name", "StatusCode", "IsCrmUIWorkflow", "IsManaged", "Id", "Url");

            FormatTextTableHandler tableActivateWorkflows = new FormatTextTableHandler();

            tableActivateWorkflows.SetHeader("Entity", "Category", "Name", "StatusCode", "IsCrmUIWorkflow", "IsManaged", "Id", "Url");

            foreach (var workflow in orderedDeactivate)
            {
                workflow.FormattedValues.TryGetValue(Workflow.Schema.Attributes.category, out string categoryName2);
                workflow.FormattedValues.TryGetValue(Workflow.Schema.Attributes.statuscode, out string statusCode2);

                tableDeactivateWorkflows.AddLine(
                    workflow.PrimaryEntity
                    , categoryName2
                    , workflow.Name
                    , statusCode2
                    , workflow.IsCrmUIWorkflow.ToString()
                    , workflow.IsManaged.ToString()
                    , workflow.Id.ToString()
                    , _comparerSource.Service2.UrlGenerator.GetSolutionComponentUrl(ComponentType.Workflow, workflow.Id)
                    );
            }

            foreach (var workflow in orderedActivate)
            {
                workflow.FormattedValues.TryGetValue(Workflow.Schema.Attributes.category, out string categoryName2);
                workflow.FormattedValues.TryGetValue(Workflow.Schema.Attributes.statuscode, out string statusCode2);

                tableActivateWorkflows.AddLine(
                    workflow.PrimaryEntity
                    , categoryName2
                    , workflow.Name
                    , statusCode2
                    , workflow.IsCrmUIWorkflow.ToString()
                    , workflow.IsManaged.ToString()
                    , workflow.Id.ToString()
                    , _comparerSource.Service2.UrlGenerator.GetSolutionComponentUrl(ComponentType.Workflow, workflow.Id)
                    );
            }

            if (tableDeactivateWorkflows.Count > 0)
            {
                content
                .AppendLine()
                .AppendLine()
                .AppendLine()
                .AppendLine(new string('-', 150))
                .AppendLine()
                .AppendLine();

                content.AppendLine().AppendLine().AppendFormat(Properties.OrganizationComparerStrings.WorkflowsToDeactivationInConnectionFormat2, ConnectionTarget.Name, tableDeactivateWorkflows.Count);

                tableDeactivateWorkflows.GetFormatedLines(false).ForEach(e => content.AppendLine().Append((_tabSpacer + e).TrimEnd()));
            }

            if (tableActivateWorkflows.Count > 0)
            {
                content
                .AppendLine()
                .AppendLine()
                .AppendLine()
                .AppendLine(new string('-', 150))
                .AppendLine()
                .AppendLine();

                content.AppendLine().AppendLine().AppendFormat(Properties.OrganizationComparerStrings.WorkflowsToActivationInConnectionFormat2, ConnectionTarget.Name, tableActivateWorkflows.Count);

                tableActivateWorkflows.GetFormatedLines(false).ForEach(e => content.AppendLine().Append((_tabSpacer + e).TrimEnd()));
            }

            foreach (var workflow in orderedDeactivate)
            {
                try
                {
                    await _comparerSource.Service2.ExecuteAsync <SetStateResponse>(new SetStateRequest()
                    {
                        EntityMoniker = workflow.ToEntityReference(),

                        State  = new Microsoft.Xrm.Sdk.OptionSetValue((int)Workflow.Schema.OptionSets.statecode.Draft_0),
                        Status = new Microsoft.Xrm.Sdk.OptionSetValue((int)Workflow.Schema.OptionSets.statuscode.Draft_0_Draft_1),
                    });
                }
                catch (Exception ex)
                {
                    var desc = DTEHelper.GetExceptionDescription(ex);

                    workflow.FormattedValues.TryGetValue(Workflow.Schema.Attributes.category, out string categoryName2);
                    workflow.FormattedValues.TryGetValue(Workflow.Schema.Attributes.statuscode, out string statusCode2);

                    var workflowDescription = tableDeactivateWorkflows.FormatLineWithHeadersInLine(
                        workflow.PrimaryEntity
                        , categoryName2
                        , workflow.Name
                        , statusCode2
                        , workflow.IsCrmUIWorkflow.ToString()
                        , workflow.IsManaged.ToString()
                        , workflow.Id.ToString()
                        , _comparerSource.Service2.UrlGenerator.GetSolutionComponentUrl(ComponentType.Workflow, workflow.Id)
                        );

                    string operationLocal = string.Format(Properties.OperationNames.DeactivatingEntityFormat2, workflow.LogicalName, ConnectionTarget.Name, workflowDescription);

                    content.AppendLine().AppendLine().AppendLine();
                    content.AppendLine(new string('-', 150)).AppendLine();
                    content.AppendFormat(Properties.OutputStrings.ExceptionWhileOperationFormat1, operationLocal).AppendLine();
                    content.AppendLine(desc);
                    content.AppendLine(new string('-', 150)).AppendLine();
                }
            }

            foreach (var workflow in orderedActivate)
            {
                try
                {
                    await _comparerSource.Service2.ExecuteAsync <SetStateResponse>(new SetStateRequest()
                    {
                        EntityMoniker = workflow.ToEntityReference(),

                        State  = new Microsoft.Xrm.Sdk.OptionSetValue((int)Workflow.Schema.OptionSets.statecode.Activated_1),
                        Status = new Microsoft.Xrm.Sdk.OptionSetValue((int)Workflow.Schema.OptionSets.statuscode.Activated_1_Activated_2),
                    });
                }
                catch (Exception ex)
                {
                    var desc = DTEHelper.GetExceptionDescription(ex);

                    workflow.FormattedValues.TryGetValue(Workflow.Schema.Attributes.category, out string categoryName2);
                    workflow.FormattedValues.TryGetValue(Workflow.Schema.Attributes.statuscode, out string statusCode2);

                    var workflowDescription = tableDeactivateWorkflows.FormatLineWithHeadersInLine(
                        workflow.PrimaryEntity
                        , categoryName2
                        , workflow.Name
                        , statusCode2
                        , workflow.IsCrmUIWorkflow.ToString()
                        , workflow.IsManaged.ToString()
                        , workflow.Id.ToString()
                        , _comparerSource.Service2.UrlGenerator.GetSolutionComponentUrl(ComponentType.Workflow, workflow.Id)
                        );

                    string operationLocal = string.Format(Properties.OperationNames.ActivatingEntityFormat3, workflow.LogicalName, ConnectionTarget.Name, workflowDescription);

                    content.AppendLine().AppendLine().AppendLine();
                    content.AppendLine(new string('-', 150)).AppendLine();
                    content.AppendFormat(Properties.OutputStrings.ExceptionWhileOperationFormat1, operationLocal).AppendLine();
                    content.AppendLine(desc);
                    content.AppendLine(new string('-', 150)).AppendLine();
                }
            }

            if (tableActivateWorkflows.Count == 0 &&
                tableDeactivateWorkflows.Count == 0
                )
            {
                content.AppendLine(Properties.OrganizationComparerStrings.WorkflowsNoDifference);
            }

            content.AppendLine().AppendLine().AppendLine(_iWriteToOutput.WriteToOutputEndOperation(null, operation));

            string fileName = string.Format("OrgTransfer Workflows States from {0} to {1} at {2}.txt"
                                            , this.ConnectionSource.Name
                                            , this.ConnectionTarget.Name
                                            , DateTime.Now.ToString("yyyy.MM.dd HH-mm-ss"));

            string filePath = Path.Combine(_folder, FileOperations.RemoveWrongSymbols(fileName));

            File.WriteAllText(filePath, content.ToString(), new UTF8Encoding(false));

            return(filePath);
        }
        private async Task <string> CheckSystemSavedQueries()
        {
            StringBuilder content = new StringBuilder();

            await _comparerSource.InitializeConnection(_iWriteToOutput, content);

            string operation = string.Format(Properties.OperationNames.CheckingSystemSavedQueriesFormat2, Connection1.Name, Connection2.Name);

            content.AppendLine(_iWriteToOutput.WriteToOutputStartOperation(null, operation));

            var task1 = _comparerSource.GetSavedQuery1Async();
            var task2 = _comparerSource.GetSavedQuery2Async();

            var list1 = await task1;

            content.AppendLine(_iWriteToOutput.WriteToOutput(null, Properties.OrganizationComparerStrings.SavedQueriesInConnectionFormat2, Connection1.Name, list1.Count));

            var list2 = await task2;

            content.AppendLine(_iWriteToOutput.WriteToOutput(null, Properties.OrganizationComparerStrings.SavedQueriesInConnectionFormat2, Connection2.Name, list2.Count));

            if (!list1.Any() && !list2.Any())
            {
                _iWriteToOutput.WriteToOutput(null, Properties.OrganizationComparerStrings.ThereIsNothingToCompare);
                _iWriteToOutput.WriteToOutputEndOperation(null, operation);
                return(null);
            }

            FormatTextTableHandler tableOnlyExistsIn1 = new FormatTextTableHandler();

            tableOnlyExistsIn1.SetHeader("Entity", "Name", "QueryType", "IsUserDefined", "IsManaged", "Id");

            FormatTextTableHandler tableOnlyExistsIn2 = new FormatTextTableHandler();

            tableOnlyExistsIn2.SetHeader("Entity", "Name", "QueryType", "IsUserDefined", "IsManaged", "Id");

            var dictDifference = new Dictionary <Tuple <string, string, string, string>, List <string> >();

            var commonList = new List <LinkedEntities <SavedQuery> >();

            foreach (var query1 in list1)
            {
                {
                    var query2 = list2.FirstOrDefault(query => query.Id == query1.Id);

                    if (query2 != null)
                    {
                        commonList.Add(new LinkedEntities <SavedQuery>(query1, query2));
                        continue;
                    }
                }

                var entityName1 = query1.ReturnedTypeCode;
                var name1       = query1.Name;
                var querytype1  = query1.QueryType.Value;

                var querytypeName1 = SavedQueryRepository.GetQueryTypeName(querytype1);

                tableOnlyExistsIn1.AddLine(
                    entityName1
                    , name1
                    , querytypeName1
                    , query1.IsUserDefined.ToString()
                    , query1.IsManaged.ToString()
                    , query1.Id.ToString());

                this.ImageBuilder.AddComponentSolution1((int)ComponentType.SavedQuery, query1.Id);
            }

            foreach (var query2 in list2)
            {
                {
                    var query1 = list1.FirstOrDefault(query => query.Id == query2.Id);

                    if (query1 != null)
                    {
                        continue;
                    }
                }

                var entityName2 = query2.ReturnedTypeCode;
                var name2       = query2.Name;
                var querytype2  = query2.QueryType.Value;

                var querytypeName2 = SavedQueryRepository.GetQueryTypeName(querytype2);

                tableOnlyExistsIn2.AddLine(
                    entityName2
                    , name2
                    , querytypeName2
                    , query2.IsUserDefined.ToString()
                    , query2.IsManaged.ToString()
                    , query2.Id.ToString()
                    );

                this.ImageBuilder.AddComponentSolution2((int)ComponentType.SavedQuery, query2.Id);
            }

            {
                var reporter = new ProgressReporter(_iWriteToOutput, commonList.Count, 5, "Processing Common Saved Queries");

                foreach (var query in commonList)
                {
                    reporter.Increase();

                    FormatTextTableHandler tabDiff = new FormatTextTableHandler();
                    tabDiff.SetHeader("Attribute", "Organization", "Value");

                    {
                        List <string> fieldsToCompare = new List <string>()
                        {
                            SavedQuery.Schema.Attributes.advancedgroupby
                            , SavedQuery.Schema.Attributes.canbedeleted
                            //, columnsetxml
                            , SavedQuery.Schema.Attributes.componentstate
                            , SavedQuery.Schema.Attributes.conditionalformatting
                            //, SavedQuery.Schema.Attributes.createdby
                            //, SavedQuery.Schema.Attributes.createdon
                            //, SavedQuery.Schema.Attributes.createdonbehalfby
                            , SavedQuery.Schema.Attributes.description
                            //, SavedQuery.Schema.Attributes.fetchxml
                            , SavedQuery.Schema.Attributes.introducedversion
                            , SavedQuery.Schema.Attributes.iscustomizable
                            , SavedQuery.Schema.Attributes.isdefault
                            //, SavedQuery.Schema.Attributes.ismanaged
                            , SavedQuery.Schema.Attributes.isprivate
                            , SavedQuery.Schema.Attributes.isquickfindquery
                            , SavedQuery.Schema.Attributes.isuserdefined
                            //, SavedQuery.Schema.Attributes.layoutxml
                            //, SavedQuery.Schema.Attributes.modifiedby
                            //, SavedQuery.Schema.Attributes.modifiedon
                            //, SavedQuery.Schema.Attributes.modifiedonbehalfby
                            , SavedQuery.Schema.Attributes.name
                            //, SavedQuery.Schema.Attributes.organizationid
                            , SavedQuery.Schema.Attributes.organizationtaborder
                            //, SavedQuery.Schema.Attributes.overwritetime
                            , SavedQuery.Schema.Attributes.queryapi
                            , SavedQuery.Schema.Attributes.queryappusage
                            , SavedQuery.Schema.Attributes.querytype
                            , SavedQuery.Schema.Attributes.returnedtypecode
                            //, SavedQuery.Schema.Attributes.savedqueryid
                            //, SavedQuery.Schema.Attributes.savedqueryidunique
                            //, SavedQuery.Schema.Attributes.solutionid
                            , SavedQuery.Schema.Attributes.statecode
                            , SavedQuery.Schema.Attributes.statuscode
                            //, SavedQuery.Schema.Attributes.supportingsolutionid
                            , SavedQuery.Schema.Attributes.versionnumber
                        };

                        foreach (var fieldName in fieldsToCompare)
                        {
                            if (ContentComparerHelper.IsEntityDifferentInField(query.Entity1, query.Entity2, fieldName))
                            {
                                var str1 = EntityDescriptionHandler.GetAttributeString(query.Entity1, fieldName, Connection1);
                                var str2 = EntityDescriptionHandler.GetAttributeString(query.Entity2, fieldName, Connection2);

                                tabDiff.AddLine(fieldName, Connection1.Name, str1);
                                tabDiff.AddLine(fieldName, Connection2.Name, str2);
                            }
                        }
                    }

                    {
                        List <string> fieldsToCompare = new List <string>()
                        {
                            SavedQuery.Schema.Attributes.fetchxml
                            , SavedQuery.Schema.Attributes.layoutxml
                            , SavedQuery.Schema.Attributes.columnsetxml
                        };

                        foreach (var fieldName in fieldsToCompare)
                        {
                            Action <XElement> action = null;

                            if (string.Equals(fieldName, SavedQuery.Schema.Attributes.layoutxml))
                            {
                                action = ContentComparerHelper.RemoveLayoutObjectCode;
                            }

                            string xml1 = query.Entity1.GetAttributeValue <string>(fieldName) ?? string.Empty;
                            string xml2 = query.Entity2.GetAttributeValue <string>(fieldName) ?? string.Empty;

                            if (!ContentComparerHelper.CompareXML(xml1, xml2, false, action).IsEqual)
                            {
                                string reason = string.Empty;

                                var compare = ContentComparerHelper.CompareXML(xml1.ToLower(), xml2.ToLower(), true, action);

                                if (compare.IsEqual)
                                {
                                    reason = "InCase";
                                }
                                else
                                {
                                    reason = compare.GetCompareDescription();
                                }

                                if (!string.IsNullOrEmpty(reason))
                                {
                                    tabDiff.AddLine(fieldName, string.Empty, string.Format(Properties.OrganizationComparerStrings.FieldDifferenceReasonFormat3, Connection1.Name, Connection2.Name, reason));
                                }
                            }
                        }
                    }

                    if (tabDiff.Count > 0)
                    {
                        var entityName1 = query.Entity1.ReturnedTypeCode;
                        var name1       = query.Entity1.Name;
                        var querytype1  = query.Entity1.QueryType.Value;

                        var querytypeName1 = SavedQueryRepository.GetQueryTypeName(querytype1);

                        var diff = tabDiff.GetFormatedLines(false);
                        this.ImageBuilder.AddComponentDifferent((int)ComponentType.SavedQuery, query.Entity1.Id, query.Entity2.Id, string.Join(Environment.NewLine, diff));

                        dictDifference.Add(Tuple.Create(entityName1, name1, querytypeName1, query.Entity1.Id.ToString()), diff);
                    }
                }
            }

            if (tableOnlyExistsIn1.Count > 0)
            {
                content
                .AppendLine()
                .AppendLine()
                .AppendLine()
                .AppendLine(new string('-', 150))
                .AppendLine()
                .AppendLine();

                content.AppendLine().AppendLine().AppendFormat("System Saved Queries ONLY EXISTS in {0}: {1}", Connection1.Name, tableOnlyExistsIn1.Count);

                tableOnlyExistsIn1.GetFormatedLines(true).ForEach(e => content.AppendLine().Append((tabSpacer + e).TrimEnd()));
            }

            if (tableOnlyExistsIn2.Count > 0)
            {
                content
                .AppendLine()
                .AppendLine()
                .AppendLine()
                .AppendLine(new string('-', 150))
                .AppendLine()
                .AppendLine();

                content.AppendLine().AppendLine().AppendFormat("System Saved Queries ONLY EXISTS in {0}: {1}", Connection2.Name, tableOnlyExistsIn2.Count);

                tableOnlyExistsIn2.GetFormatedLines(true).ForEach(e => content.AppendLine().Append((tabSpacer + e).TrimEnd()));
            }

            if (dictDifference.Count > 0)
            {
                content
                .AppendLine()
                .AppendLine()
                .AppendLine()
                .AppendLine(new string('-', 150))
                .AppendLine()
                .AppendLine();

                content.AppendLine().AppendLine().AppendFormat("System Saved Queries DIFFERENT in {0} and {1}: {2}", Connection1.Name, Connection2.Name, dictDifference.Count);

                FormatTextTableHandler tableDifference = new FormatTextTableHandler();
                tableDifference.SetHeader("Entity", "Name", "QueryType", "Id");

                foreach (var template in dictDifference)
                {
                    tableDifference.CalculateLineLengths(template.Key.Item1, template.Key.Item2, template.Key.Item3, template.Key.Item4);
                }

                foreach (var template in dictDifference
                         .OrderBy(w => w.Key.Item1)
                         .ThenBy(w => w.Key.Item2)
                         .ThenBy(w => w.Key.Item3)
                         .ThenBy(w => w.Key.Item4)
                         )
                {
                    content.AppendLine().Append(tabSpacer + tableDifference.FormatLine(template.Key.Item1, template.Key.Item2, template.Key.Item3, template.Key.Item4));

                    foreach (var str in template.Value)
                    {
                        content.AppendLine().Append(tabSpacer + tabSpacer + str);
                    }
                }
            }

            if (tableOnlyExistsIn2.Count == 0 &&
                tableOnlyExistsIn1.Count == 0 &&
                dictDifference.Count == 0
                )
            {
                content.AppendLine("No difference in System Saved Queries.");
            }

            content.AppendLine().AppendLine().AppendLine(_iWriteToOutput.WriteToOutputEndOperation(null, operation));

            string fileName = EntityFileNameFormatter.GetDifferenceConnectionsForFieldFileName(_OrgOrgName, "System Saved Queries");

            string filePath = Path.Combine(_folder, FileOperations.RemoveWrongSymbols(fileName));

            File.WriteAllText(filePath, content.ToString(), new UTF8Encoding(false));

            await SaveOrganizationDifferenceImage();

            return(filePath);
        }
        private async Task <string> CheckSystemSavedQueryVisualizations()
        {
            StringBuilder content = new StringBuilder();

            await _comparerSource.InitializeConnection(_iWriteToOutput, content);

            string operation = string.Format(Properties.OperationNames.CheckingSystemChartsFormat2, Connection1.Name, Connection2.Name);

            content.AppendLine(_iWriteToOutput.WriteToOutputStartOperation(null, operation));

            var task1 = _comparerSource.GetSavedQueryVisualization1Async();
            var task2 = _comparerSource.GetSavedQueryVisualization2Async();

            var list1 = await task1;

            content.AppendLine(_iWriteToOutput.WriteToOutput(null, Properties.OrganizationComparerStrings.SavedQueryVisualizationsInConnectionFormat2, Connection1.Name, list1.Count));

            var list2 = await task2;

            content.AppendLine(_iWriteToOutput.WriteToOutput(null, Properties.OrganizationComparerStrings.SavedQueryVisualizationsInConnectionFormat2, Connection2.Name, list2.Count));

            if (!list1.Any() && !list2.Any())
            {
                _iWriteToOutput.WriteToOutput(null, Properties.OrganizationComparerStrings.ThereIsNothingToCompare);
                _iWriteToOutput.WriteToOutputEndOperation(null, operation);
                return(null);
            }

            FormatTextTableHandler tableOnlyExistsIn1 = new FormatTextTableHandler();

            tableOnlyExistsIn1.SetHeader("Entity", "Name", "IsManaged", "Id");

            FormatTextTableHandler tableOnlyExistsIn2 = new FormatTextTableHandler();

            tableOnlyExistsIn2.SetHeader("Entity", "Name", "IsManaged", "Id");

            var dictDifference = new Dictionary <Tuple <string, string, string>, List <string> >();

            var commonList = new List <LinkedEntities <SavedQueryVisualization> >();

            foreach (var chart1 in list1)
            {
                {
                    var chart2 = list2.FirstOrDefault(chart => chart.Id == chart1.Id);

                    if (chart2 != null)
                    {
                        commonList.Add(new LinkedEntities <SavedQueryVisualization>(chart1, chart2));
                        continue;
                    }
                }

                var entityName1 = chart1.PrimaryEntityTypeCode;
                var name1       = chart1.Name;

                tableOnlyExistsIn1.AddLine(entityName1, name1, chart1.IsManaged.ToString(), chart1.Id.ToString());

                this.ImageBuilder.AddComponentSolution1((int)ComponentType.SavedQueryVisualization, chart1.Id);
            }

            foreach (var chart2 in list2)
            {
                var entityName2 = chart2.PrimaryEntityTypeCode;
                var name2       = chart2.Name;

                {
                    var chart1 = list1.FirstOrDefault(chart => chart.Id == chart2.Id);

                    if (chart1 != null)
                    {
                        continue;
                    }
                }

                tableOnlyExistsIn2.AddLine(entityName2, name2, chart2.IsManaged.ToString(), chart2.Id.ToString());

                this.ImageBuilder.AddComponentSolution2((int)ComponentType.SavedQueryVisualization, chart2.Id);
            }

            {
                var reporter = new ProgressReporter(_iWriteToOutput, commonList.Count, 5, "Processing Common Saved Query Visualizations (Charts)");

                foreach (var chart in commonList)
                {
                    var chart1 = chart.Entity1;
                    var chart2 = chart.Entity2;

                    FormatTextTableHandler tabDiff = new FormatTextTableHandler();
                    tabDiff.SetHeader("Attribute", "Organization", "Value");

                    {
                        List <string> fieldsToCompare = new List <string>()
                        {
                            SavedQueryVisualization.Schema.Attributes.componentstate
                            //, SavedQueryVisualization.Schema.Attributes.createdby
                            //, SavedQueryVisualization.Schema.Attributes.createdon
                            //, SavedQueryVisualization.Schema.Attributes.createdonbehalfby
                            //, SavedQueryVisualization.Schema.Attributes.datadescription
                            , SavedQueryVisualization.Schema.Attributes.description
                            , SavedQueryVisualization.Schema.Attributes.introducedversion
                            , SavedQueryVisualization.Schema.Attributes.iscustomizable
                            , SavedQueryVisualization.Schema.Attributes.isdefault
                            //, SavedQueryVisualization.Schema.Attributes.ismanaged
                            //, SavedQueryVisualization.Schema.Attributes.modifiedby
                            //, SavedQueryVisualization.Schema.Attributes.modifiedon
                            //, SavedQueryVisualization.Schema.Attributes.modifiedonbehalfby
                            , SavedQueryVisualization.Schema.Attributes.name
                            //, SavedQueryVisualization.Schema.Attributes.organizationid
                            //, SavedQueryVisualization.Schema.Attributes.overwritetime
                            //, SavedQueryVisualization.Schema.Attributes.presentationdescription
                            , SavedQueryVisualization.Schema.Attributes.primaryentitytypecode
                            //, SavedQueryVisualization.Schema.Attributes.savedqueryvisualizationid
                            //, SavedQueryVisualization.Schema.Attributes.savedqueryvisualizationidunique
                            //, SavedQueryVisualization.Schema.Attributes.solutionid
                            //, SavedQueryVisualization.Schema.Attributes.supportingsolutionid
                            , SavedQueryVisualization.Schema.Attributes.versionnumber
                            , SavedQueryVisualization.Schema.Attributes.webresourceid
                        };

                        foreach (var fieldName in fieldsToCompare)
                        {
                            if (ContentComparerHelper.IsEntityDifferentInField(chart1, chart2, fieldName))
                            {
                                var str1 = EntityDescriptionHandler.GetAttributeString(chart1, fieldName, Connection1);
                                var str2 = EntityDescriptionHandler.GetAttributeString(chart2, fieldName, Connection2);

                                tabDiff.AddLine(fieldName, Connection1.Name, str1);
                                tabDiff.AddLine(fieldName, Connection2.Name, str2);
                            }
                        }
                    }

                    var entityName1 = chart1.PrimaryEntityTypeCode;
                    var name1       = chart1.Name;

                    {
                        List <string> fieldsToCompare = new List <string>()
                        {
                            SavedQueryVisualization.Schema.Attributes.datadescription
                            , SavedQueryVisualization.Schema.Attributes.presentationdescription
                        };

                        foreach (var fieldName in fieldsToCompare)
                        {
                            string xml1 = chart1.GetAttributeValue <string>(fieldName) ?? string.Empty;
                            string xml2 = chart2.GetAttributeValue <string>(fieldName) ?? string.Empty;

                            if (!ContentComparerHelper.CompareXML(xml1, xml2).IsEqual)
                            {
                                string reason = string.Empty;

                                var compare = ContentComparerHelper.CompareXML(xml1.ToLower(), xml2.ToLower(), true);

                                if (compare.IsEqual)
                                {
                                    reason = "InCase";
                                }
                                else
                                {
                                    reason = compare.GetCompareDescription();
                                }

                                if (!string.IsNullOrEmpty(reason))
                                {
                                    tabDiff.AddLine(fieldName, string.Empty, string.Format(Properties.OrganizationComparerStrings.FieldDifferenceReasonFormat3, Connection1.Name, Connection2.Name, reason));
                                }
                            }
                        }
                    }

                    if (tabDiff.Count > 0)
                    {
                        var diff = tabDiff.GetFormatedLines(false);
                        this.ImageBuilder.AddComponentDifferent((int)ComponentType.SavedQueryVisualization, chart1.Id, chart2.Id, string.Join(Environment.NewLine, diff));

                        dictDifference.Add(Tuple.Create(entityName1, name1, chart1.Id.ToString()), diff);
                    }
                }
            }

            if (tableOnlyExistsIn1.Count > 0)
            {
                content
                .AppendLine()
                .AppendLine()
                .AppendLine()
                .AppendLine(new string('-', 150))
                .AppendLine()
                .AppendLine();

                content.AppendLine().AppendLine().AppendFormat("System Saved Query Visualizations (Charts) ONLY EXISTS in {0}: {1}", Connection1.Name, tableOnlyExistsIn1.Count);

                tableOnlyExistsIn1.GetFormatedLines(true).ForEach(e => content.AppendLine().Append((tabSpacer + e).TrimEnd()));
            }

            if (tableOnlyExistsIn2.Count > 0)
            {
                content
                .AppendLine()
                .AppendLine()
                .AppendLine()
                .AppendLine(new string('-', 150))
                .AppendLine()
                .AppendLine();

                content.AppendLine().AppendLine().AppendFormat("System Saved Query Visualizations (Charts) ONLY EXISTS in {0}: {1}", Connection2.Name, tableOnlyExistsIn2.Count);

                tableOnlyExistsIn2.GetFormatedLines(true).ForEach(e => content.AppendLine().Append((tabSpacer + e).TrimEnd()));
            }

            if (dictDifference.Count > 0)
            {
                content
                .AppendLine()
                .AppendLine()
                .AppendLine()
                .AppendLine(new string('-', 150))
                .AppendLine()
                .AppendLine();

                content.AppendLine().AppendLine().AppendFormat("System Saved Query Visualizations (Charts) DIFFERENT in {0} and {1}: {2}", Connection1.Name, Connection2.Name, dictDifference.Count);

                FormatTextTableHandler tableDifference = new FormatTextTableHandler();
                tableDifference.SetHeader("Entity", "Name", "Id");

                foreach (var template in dictDifference)
                {
                    tableDifference.CalculateLineLengths(template.Key.Item1, template.Key.Item2, template.Key.Item3);
                }

                foreach (var template in dictDifference
                         .OrderBy(w => w.Key.Item1)
                         .ThenBy(w => w.Key.Item2)
                         .ThenBy(w => w.Key.Item3)
                         )
                {
                    content.AppendLine().Append(tabSpacer + tableDifference.FormatLine(template.Key.Item1, template.Key.Item2, template.Key.Item3));

                    foreach (var str in template.Value)
                    {
                        content.AppendLine().Append(tabSpacer + tabSpacer + str);
                    }
                }
            }

            if (tableOnlyExistsIn2.Count == 0 &&
                tableOnlyExistsIn1.Count == 0 &&
                dictDifference.Count == 0
                )
            {
                content.AppendLine("No difference in System Saved Query Visualizations (Charts).");
            }

            content.AppendLine().AppendLine().AppendLine(_iWriteToOutput.WriteToOutputEndOperation(null, operation));

            string fileName = EntityFileNameFormatter.GetDifferenceConnectionsForFieldFileName(_OrgOrgName, "Saved Query Visualizations (Charts)");

            string filePath = Path.Combine(_folder, FileOperations.RemoveWrongSymbols(fileName));

            File.WriteAllText(filePath, content.ToString(), new UTF8Encoding(false));

            await SaveOrganizationDifferenceImage();

            return(filePath);
        }
        private async Task <string> CheckSystemForms()
        {
            StringBuilder content = new StringBuilder();

            await _comparerSource.InitializeConnection(_iWriteToOutput, content);

            string operation = string.Format(Properties.OperationNames.CheckingSystemFormsFormat2, Connection1.Name, Connection2.Name);

            content.AppendLine(_iWriteToOutput.WriteToOutputStartOperation(null, operation));

            FormDescriptionHandler handler1 = new FormDescriptionHandler(ImageBuilder.Descriptor1, new DependencyRepository(_comparerSource.Service1))
            {
                WithManagedInfo         = false,
                WithDependentComponents = false,
            };
            FormDescriptionHandler handler2 = new FormDescriptionHandler(ImageBuilder.Descriptor2, new DependencyRepository(_comparerSource.Service2))
            {
                WithManagedInfo         = false,
                WithDependentComponents = false,
            };

            var task1 = _comparerSource.GetSystemForm1Async();
            var task2 = _comparerSource.GetSystemForm2Async();

            var list1 = await task1;

            content.AppendLine(_iWriteToOutput.WriteToOutput(null, Properties.OrganizationComparerStrings.SystemFormsInConnectionFormat2, Connection1.Name, list1.Count));

            var list2 = await task2;

            content.AppendLine(_iWriteToOutput.WriteToOutput(null, Properties.OrganizationComparerStrings.SystemFormsInConnectionFormat2, Connection2.Name, list2.Count));

            if (!list1.Any() && !list2.Any())
            {
                _iWriteToOutput.WriteToOutput(null, Properties.OrganizationComparerStrings.ThereIsNothingToCompare);
                _iWriteToOutput.WriteToOutputEndOperation(null, operation);
                return(null);
            }

            FormatTextTableHandler tableOnlyExistsIn1 = new FormatTextTableHandler();

            tableOnlyExistsIn1.SetHeader("Entity", "Type", "Name", "IsManaged", "Id");

            FormatTextTableHandler tableOnlyExistsIn2 = new FormatTextTableHandler();

            tableOnlyExistsIn2.SetHeader("Entity", "Type", "Name", "IsManaged", "Id");

            var dictDifference = new Dictionary <Tuple <string, string, string, string>, List <string> >();

            var commonList = new List <LinkedEntities <SystemForm> >();

            foreach (var form1 in list1)
            {
                {
                    var form2 = list2.FirstOrDefault(form => form.Id == form1.Id);

                    if (form2 != null)
                    {
                        commonList.Add(new LinkedEntities <SystemForm>(form1, form2));
                        continue;
                    }
                }

                var entityName1 = form1.ObjectTypeCode;
                var name1       = form1.Name;

                string typeName1 = form1.FormattedValues[SystemForm.Schema.Attributes.type];

                tableOnlyExistsIn1.AddLine(entityName1, typeName1, name1, form1.IsManaged.ToString(), form1.Id.ToString());

                this.ImageBuilder.AddComponentSolution1((int)ComponentType.SystemForm, form1.Id);
            }

            foreach (var form2 in list2)
            {
                {
                    var form1 = list1.FirstOrDefault(form => form.Id == form2.Id);

                    if (form1 != null)
                    {
                        continue;
                    }
                }

                var entityName2 = form2.ObjectTypeCode;
                var name2       = form2.Name;

                string typeName2 = form2.FormattedValues[SystemForm.Schema.Attributes.type];

                tableOnlyExistsIn2.AddLine(entityName2, typeName2, name2, form2.IsManaged.ToString(), form2.Id.ToString());

                this.ImageBuilder.AddComponentSolution2((int)ComponentType.SystemForm, form2.Id);
            }

            {
                var reporter = new ProgressReporter(_iWriteToOutput, commonList.Count, 5, "Processing Common Forms");

                foreach (var form in commonList)
                {
                    reporter.Increase();

                    FormatTextTableHandler tabDiff = new FormatTextTableHandler();
                    tabDiff.SetHeader("Attribute", "Organization", "Value");

                    {
                        List <string> fieldsToCompare = new List <string>()
                        {
                            //SystemForm.Schema.Attributes.ancestorformid
                            SystemForm.Schema.Attributes.canbedeleted
                            , SystemForm.Schema.Attributes.componentstate
                            , SystemForm.Schema.Attributes.description
                            , SystemForm.Schema.Attributes.formactivationstate
                            , SystemForm.Schema.Attributes.formpresentation
                            //, SystemForm.Schema.Attributes.formxml
                            //, SystemForm.Schema.Attributes.formxmlmanaged
                            , SystemForm.Schema.Attributes.introducedversion
                            , SystemForm.Schema.Attributes.isairmerged
                            , SystemForm.Schema.Attributes.iscustomizable
                            , SystemForm.Schema.Attributes.isdefault
                            //, SystemForm.Schema.Attributes.ismanaged
                            , SystemForm.Schema.Attributes.istabletenabled
                            , SystemForm.Schema.Attributes.name
                            , SystemForm.Schema.Attributes.objecttypecode
                            //, SystemForm.Schema.Attributes.organizationid
                            //, SystemForm.Schema.Attributes.overwritetime
                            //, SystemForm.Schema.Attributes.publishedon
                            //, SystemForm.Schema.Attributes.solutionid
                            //, SystemForm.Schema.Attributes.supportingsolutionid
                            , SystemForm.Schema.Attributes.type
                            , SystemForm.Schema.Attributes.version
                            , SystemForm.Schema.Attributes.versionnumber
                        };

                        foreach (var fieldName in fieldsToCompare)
                        {
                            if (ContentComparerHelper.IsEntityDifferentInField(form.Entity1, form.Entity2, fieldName))
                            {
                                var str1 = EntityDescriptionHandler.GetAttributeString(form.Entity1, fieldName, Connection1);
                                var str2 = EntityDescriptionHandler.GetAttributeString(form.Entity2, fieldName, Connection2);

                                tabDiff.AddLine(fieldName, Connection1.Name, str1);
                                tabDiff.AddLine(fieldName, Connection2.Name, str2);
                            }
                        }
                    }

                    string typeName1 = form.Entity1.FormattedValues[SystemForm.Schema.Attributes.type];
                    string typeName2 = form.Entity2.FormattedValues[SystemForm.Schema.Attributes.type];

                    {
                        List <string> fieldsToCompare = new List <string>()
                        {
                            SystemForm.Schema.Attributes.formxml
                        };

                        foreach (var fieldName in fieldsToCompare)
                        {
                            string formXml1 = form.Entity1.GetAttributeValue <string>(fieldName) ?? string.Empty;
                            string formXml2 = form.Entity2.GetAttributeValue <string>(fieldName) ?? string.Empty;

                            if (!ContentComparerHelper.CompareXML(formXml1, formXml2).IsEqual)
                            {
                                string descReason = string.Empty;

                                if (ContentComparerHelper.TryParseXml(formXml1, out var doc1) && ContentComparerHelper.TryParseXml(formXml2, out var doc2))
                                {
                                    string desc1 = await handler1.GetFormDescriptionAsync(doc1, form.Entity1.ObjectTypeCode, form.Entity1.Id, form.Entity1.Name, typeName1);

                                    string desc2 = await handler2.GetFormDescriptionAsync(doc2, form.Entity2.ObjectTypeCode, form.Entity2.Id, form.Entity2.Name, typeName2);

                                    if (!string.Equals(desc1, desc2))
                                    {
                                        var compare = ContentComparerHelper.CompareText(desc1.ToLower(), desc2.ToLower());

                                        if (compare.IsEqual)
                                        {
                                            descReason = "InCase";
                                        }
                                        else
                                        {
                                            descReason = compare.GetCompareDescription();
                                        }
                                    }
                                }

                                string formReason = string.Empty;

                                {
                                    if (ContentComparerHelper.TryParseXml(formXml1, out var docCorrected1) &&
                                        ContentComparerHelper.TryParseXml(formXml2, out var docCorrected2)
                                        )
                                    {
                                        handler1.ReplaceRoleToRoleTemplates(docCorrected1);
                                        handler2.ReplaceRoleToRoleTemplates(docCorrected2);

                                        if (ContentComparerHelper.CompareXML(docCorrected1.ToString(), docCorrected2.ToString()).IsEqual)
                                        {
                                            formReason = string.Empty;
                                        }
                                        else
                                        {
                                            var compare = ContentComparerHelper.CompareXML(docCorrected1.ToString().ToLower(), docCorrected2.ToString().ToLower(), true);

                                            if (compare.IsEqual)
                                            {
                                                formReason = "InCase";
                                            }
                                            else
                                            {
                                                formReason = compare.GetCompareDescription();
                                            }
                                        }
                                    }
                                    else
                                    {
                                        var compare = ContentComparerHelper.CompareXML(formXml1.ToLower(), formXml2.ToLower(), true);

                                        if (compare.IsEqual)
                                        {
                                            formReason = "InCase";
                                        }
                                        else
                                        {
                                            formReason = compare.GetCompareDescription();
                                        }
                                    }
                                }

                                if (!string.IsNullOrEmpty(formReason))
                                {
                                    tabDiff.AddLine(fieldName, string.Empty, string.Format(Properties.OrganizationComparerStrings.FieldDifferenceReasonFormat3, Connection1.Name, Connection2.Name, formReason));
                                }

                                if (!string.IsNullOrEmpty(descReason))
                                {
                                    tabDiff.AddLine(fieldName + "Description", string.Empty, string.Format(Properties.OrganizationComparerStrings.FieldDifferenceReasonFormat3, Connection1.Name, Connection2.Name, descReason));
                                }
                            }
                        }
                    }

                    if (tabDiff.Count > 0)
                    {
                        var diff = tabDiff.GetFormatedLines(false);
                        this.ImageBuilder.AddComponentDifferent((int)ComponentType.SystemForm, form.Entity1.Id, form.Entity2.Id, string.Join(Environment.NewLine, diff));

                        var entityName1 = form.Entity1.ObjectTypeCode;
                        var name1       = form.Entity1.Name;

                        dictDifference.Add(Tuple.Create(entityName1, typeName1, name1, form.Entity1.Id.ToString()), diff);
                    }
                }
            }

            if (tableOnlyExistsIn1.Count > 0)
            {
                content
                .AppendLine()
                .AppendLine()
                .AppendLine()
                .AppendLine(new string('-', 150))
                .AppendLine()
                .AppendLine();

                content.AppendLine().AppendLine().AppendFormat("System Forms ONLY EXISTS in {0}: {1}", Connection1.Name, tableOnlyExistsIn1.Count);

                tableOnlyExistsIn1.GetFormatedLines(true).ForEach(e => content.AppendLine().Append((tabSpacer + e).TrimEnd()));
            }

            if (tableOnlyExistsIn2.Count > 0)
            {
                content
                .AppendLine()
                .AppendLine()
                .AppendLine()
                .AppendLine(new string('-', 150))
                .AppendLine()
                .AppendLine();

                content.AppendLine().AppendLine().AppendFormat("System Forms ONLY EXISTS in {0}: {1}", Connection2.Name, tableOnlyExistsIn2.Count);

                tableOnlyExistsIn2.GetFormatedLines(true).ForEach(e => content.AppendLine().Append((tabSpacer + e).TrimEnd()));
            }

            if (dictDifference.Count > 0)
            {
                content
                .AppendLine()
                .AppendLine()
                .AppendLine()
                .AppendLine(new string('-', 150))
                .AppendLine()
                .AppendLine();

                content.AppendLine().AppendLine().AppendFormat("System Forms DIFFERENT in {0} and {1}: {2}", Connection1.Name, Connection2.Name, dictDifference.Count);

                FormatTextTableHandler tableDifference = new FormatTextTableHandler();
                tableDifference.SetHeader("Entity", "Type", "Name", "Id");

                foreach (var template in dictDifference)
                {
                    tableDifference.CalculateLineLengths(template.Key.Item1, template.Key.Item2, template.Key.Item3, template.Key.Item4);
                }

                foreach (var template in dictDifference
                         .OrderBy(w => w.Key.Item1)
                         .ThenBy(w => w.Key.Item2)
                         .ThenBy(w => w.Key.Item3)
                         .ThenBy(w => w.Key.Item4)
                         )
                {
                    content.AppendLine().Append(tabSpacer + tableDifference.FormatLine(template.Key.Item1, template.Key.Item2, template.Key.Item3, template.Key.Item4));

                    foreach (var str in template.Value)
                    {
                        content.AppendLine().Append(tabSpacer + tabSpacer + str);
                    }
                }
            }

            if (tableOnlyExistsIn2.Count == 0 &&
                tableOnlyExistsIn1.Count == 0 &&
                dictDifference.Count == 0
                )
            {
                content.AppendLine("No difference in System Forms.");
            }

            content.AppendLine().AppendLine().AppendLine(_iWriteToOutput.WriteToOutputEndOperation(null, operation));

            string fileName = EntityFileNameFormatter.GetDifferenceConnectionsForFieldFileName(_OrgOrgName, "System Forms");

            string filePath = Path.Combine(_folder, FileOperations.RemoveWrongSymbols(fileName));

            File.WriteAllText(filePath, content.ToString(), new UTF8Encoding(false));

            await SaveOrganizationDifferenceImage();

            return(filePath);
        }