public void GenerateDescription(StringBuilder builder, IEnumerable <SolutionComponent> components, bool withManaged, bool withSolutionInfo, bool withUrls)
        {
            FormatTextTableHandler handler = new FormatTextTableHandler();

            handler.SetHeader("EntityName", "DisplayName", "IsCustomizable", "Behavior");

            if (withManaged)
            {
                handler.AppendHeader("IsManaged");
            }

            if (withUrls)
            {
                handler.AppendHeader("Url");
            }

            foreach (var comp in components)
            {
                string behavior = SolutionComponent.GetRootComponentBehaviorName(comp.RootComponentBehavior?.Value);

                EntityMetadata metaData = _source.GetEntityMetadata(comp.ObjectId.Value);

                if (metaData != null)
                {
                    List <string> values = new List <string>();

                    values.AddRange(new[]
                    {
                        metaData.LogicalName
                        , metaData.DisplayName?.UserLocalizedLabel?.Label
                        , metaData.IsCustomizable?.Value.ToString()
                        , behavior
                    });

                    if (withManaged)
                    {
                        values.Add(metaData.IsManaged.ToString());
                    }

                    if (withUrls)
                    {
                        values.Add(_source.Service.ConnectionData?.GetEntityMetadataUrl(metaData.MetadataId.Value));
                    }

                    handler.AddLine(values);
                }
                else
                {
                    handler.AddLine(comp.ObjectId.ToString(), behavior);
                }
            }

            List <string> lines = handler.GetFormatedLines(true);

            lines.ForEach(item => builder.AppendFormat(formatSpacer, item).AppendLine());
        }
Esempio n. 2
0
        public string GenerateDescriptionSingle(SolutionComponent solutionComponent, bool withManaged, bool withSolutionInfo, bool withUrls)
        {
            if (solutionComponent == null)
            {
                return(null);
            }

            var entityInput = GetEntity <Entity>(solutionComponent.ObjectId.Value);

            if (entityInput != null)
            {
                FormatTextTableHandler handler = GetDescriptionHeader(withManaged, withSolutionInfo, withUrls, AppendIntoTableHeaderSingle);

                var behavior = SolutionComponent.GetRootComponentBehaviorName(solutionComponent?.RootComponentBehavior?.Value);

                List <string> values = GetDescriptionValues(entityInput, behavior, withManaged, withSolutionInfo, withUrls, AppendIntoValuesSingle);

                handler.AddLine(values);

                var str = handler.GetFormatedLinesWithHeadersInLine(false).FirstOrDefault();

                return(string.Format("{0} {1}", entityInput.LogicalName, str));
            }

            return(solutionComponent.ToString());
        }
        public string GenerateDescriptionSingle(SolutionComponent solutionComponent, bool withManaged, bool withSolutionInfo, bool withUrls)
        {
            EntityKeyMetadata metaData = _source.GetEntityKeyMetadata(solutionComponent.ObjectId.Value);

            if (metaData != null)
            {
                string behavior = SolutionComponent.GetRootComponentBehaviorName(solutionComponent.RootComponentBehavior?.Value);

                FormatTextTableHandler handler = new FormatTextTableHandler();
                handler.SetHeader("EntityKeyName", "IsCustomizable", "Behavior");

                if (withManaged)
                {
                    handler.AppendHeader("IsManaged");
                }

                handler.AppendHeader("KeyAttributes");

                if (withUrls)
                {
                    handler.AppendHeader("Url");
                }

                List <string> values = new List <string>();

                values.AddRange(new[]
                {
                    string.Format("{0}.{1}", metaData.EntityLogicalName, metaData.LogicalName)
                    , metaData.IsCustomizable?.Value.ToString()
                    , behavior
                });

                if (withManaged)
                {
                    values.Add(metaData.IsManaged.ToString());
                }

                values.Add(string.Join(",", metaData.KeyAttributes.OrderBy(s => s)));

                if (withUrls)
                {
                    var entityMetadata = _source.GetEntityMetadata(metaData.EntityLogicalName);

                    if (entityMetadata != null)
                    {
                        values.Add(_source.Service.ConnectionData?.GetEntityKeyMetadataUrl(entityMetadata.MetadataId.Value, metaData.MetadataId.Value));
                    }
                }

                handler.AddLine(values);

                var str = handler.GetFormatedLinesWithHeadersInLine(false).FirstOrDefault();

                return(string.Format("{0} {1}", this.ComponentTypeEnum.ToString(), str));
            }

            return(solutionComponent.ToString());
        }
        public string GenerateDescriptionSingle(SolutionComponent solutionComponent, bool withManaged, bool withSolutionInfo, bool withUrls)
        {
            if (this._source.AllOptionSetMetadata.Any())
            {
                if (this._source.AllOptionSetMetadata.ContainsKey(solutionComponent.ObjectId.Value))
                {
                    var optionSet = this._source.AllOptionSetMetadata[solutionComponent.ObjectId.Value];

                    string behavior = SolutionComponent.GetRootComponentBehaviorName(solutionComponent.RootComponentBehavior?.Value);

                    FormatTextTableHandler handler = new FormatTextTableHandler();
                    handler.SetHeader("OptionSetName", "IsCustomizable", "Behavior");

                    if (withManaged)
                    {
                        handler.AppendHeader("IsManaged");
                    }

                    if (withUrls)
                    {
                        handler.AppendHeader("Url");
                    }

                    List <string> values = new List <string>();

                    values.AddRange(new[]
                    {
                        optionSet.Name
                        , optionSet.IsCustomizable?.Value.ToString()
                        , behavior
                    });

                    if (withManaged)
                    {
                        values.Add(optionSet.IsManaged.ToString());
                    }

                    if (withUrls)
                    {
                        values.Add(_source.Service.ConnectionData?.GetGlobalOptionSetUrl(optionSet.MetadataId.Value));
                    }

                    handler.AddLine(values);

                    var str = handler.GetFormatedLinesWithHeadersInLine(false).FirstOrDefault();

                    return(string.Format("{0} {1}", this.ComponentTypeEnum.ToString(), str));
                }
            }

            return(solutionComponent.ToString());
        }
Esempio n. 5
0
        public void GenerateDescription(StringBuilder builder, IEnumerable <SolutionComponent> components, bool withManaged, bool withSolutionInfo, bool withUrls)
        {
            FormatTextTableHandler handler = new FormatTextTableHandler();

            handler.SetHeader("DependencyFeatureId", "Behavior");

            foreach (var comp in components)
            {
                string behavior = SolutionComponent.GetRootComponentBehaviorName(comp.RootComponentBehavior?.Value);

                handler.AddLine(comp.ObjectId.ToString(), string.Empty, behavior);
            }

            List <string> lines = handler.GetFormatedLines(true);

            lines.ForEach(item => builder.AppendFormat(formatSpacer, item).AppendLine());
        }
Esempio n. 6
0
        public string GenerateDescriptionSingle(SolutionComponent component, bool withManaged, bool withSolutionInfo, bool withUrls)
        {
            if (this.AllManagedProperties.Any())
            {
                if (this.AllManagedProperties.ContainsKey(component.ObjectId.Value))
                {
                    var managedProperty = this.AllManagedProperties[component.ObjectId.Value];

                    FormatTextTableHandler handler = new FormatTextTableHandler();
                    handler.SetHeader(
                        "LogicalName"
                        , "DisplayName"
                        , "Description"
                        , "EnablesEntityName"
                        , "EnablesAttributeName"
                        , "ErrorCode"
                        , "EvaluationPriority"
                        , "IsPrivate"
                        , "IsGlobalForOperation"
                        , "ManagedPropertyType"
                        , "Operation"
                        );

                    handler.AddLine(
                        managedProperty.LogicalName
                        , CreateFileHandler.GetLocalizedLabel(managedProperty.DisplayName)
                        , CreateFileHandler.GetLocalizedLabel(managedProperty.Description)
                        , managedProperty.EnablesEntityName
                        , managedProperty.EnablesAttributeName
                        , managedProperty.ErrorCode.ToString()
                        , managedProperty.EvaluationPriority.ToString()
                        , managedProperty.IsPrivate.ToString()
                        , managedProperty.IsGlobalForOperation.ToString()
                        , managedProperty.ManagedPropertyType.ToString()
                        , managedProperty.Operation.ToString()
                        );

                    var str = handler.GetFormatedLinesWithHeadersInLine(false).FirstOrDefault();

                    return(string.Format("{0} {1}", this.ComponentTypeEnum.ToString(), str));
                }
            }

            return(component.ToString());
        }
        private string GenerateDescriptionSingleInternal(EntityMetadata metaData, int?behaviorCode, bool withUrls, bool withManaged, bool withSolutionInfo)
        {
            string behavior = SolutionComponent.GetRootComponentBehaviorName(behaviorCode);

            FormatTextTableHandler handler = new FormatTextTableHandler();

            handler.SetHeader("EntityName", "DisplayName", "IsCustomizable", "Behavior");

            if (withManaged)
            {
                handler.AppendHeader("IsManaged");
            }

            if (withUrls)
            {
                handler.AppendHeader("Url");
            }

            List <string> values = new List <string>();

            values.AddRange(new[]
            {
                metaData.LogicalName
                , metaData.DisplayName?.UserLocalizedLabel?.Label
                , metaData.IsCustomizable?.Value.ToString()
                , behavior
            });

            if (withManaged)
            {
                values.Add(metaData.IsManaged.ToString());
            }

            if (withUrls)
            {
                values.Add(_source.Service.ConnectionData?.GetEntityMetadataUrl(metaData.MetadataId.Value));
            }

            handler.AddLine(values);

            var str = handler.GetFormatedLinesWithHeadersInLine(false).FirstOrDefault();

            return(string.Format("{0} {1}", this.ComponentTypeEnum.ToString(), str));
        }
Esempio n. 8
0
        public void GenerateDescription(StringBuilder builder, IEnumerable <SolutionComponent> components, bool withManaged, bool withSolutionInfo, bool withUrls)
        {
            var list = GetEntities <Entity>(components.Select(c => c.ObjectId));

            {
                var hash      = new HashSet <Guid>(list.Select(en => en.Id));
                var notFinded = components.Where(en => !hash.Contains(en.ObjectId.Value)).ToList();
                if (notFinded.Any())
                {
                    builder.AppendFormat(formatSpacer, unknowedMessage).AppendLine();
                    foreach (var item in notFinded)
                    {
                        var behavior = SolutionComponent.GetRootComponentBehaviorName(item.RootComponentBehavior?.Value);

                        builder.AppendFormat(formatSpacer, item.ToString(), string.Format(formatSpacer, behavior)).AppendLine();
                    }
                }
            }

            FormatTextTableHandler handler = GetDescriptionHeader(withManaged, withSolutionInfo, withUrls, AppendIntoTableHeader);

            foreach (var entity in list)
            {
                var solutionComponent = components.SingleOrDefault(e => e.ObjectId == entity.Id);

                var behavior = SolutionComponent.GetRootComponentBehaviorName(solutionComponent?.RootComponentBehavior?.Value);

                List <string> values = GetDescriptionValues(entity, behavior, withManaged, withSolutionInfo, withUrls, AppendIntoValues);

                handler.AddLine(values);
            }

            List <string> lines = handler.GetFormatedLines(true);

            lines.ForEach(item => builder.AppendFormat(formatSpacer, item).AppendLine());
        }
Esempio n. 9
0
        private async Task ShowingWebResourcesDependentComponents(ConnectionData connectionData, CommonConfiguration commonConfig, List <SelectedFile> selectedFiles)
        {
            var service = await ConnectAndWriteToOutputAsync(connectionData);

            if (service == null)
            {
                return;
            }

            StringBuilder content = new StringBuilder();

            content.AppendLine(Properties.OutputStrings.ConnectingToCRM);
            content.AppendLine(connectionData.GetConnectionDescription());
            content.AppendFormat(Properties.OutputStrings.CurrentServiceEndpointFormat1, service.CurrentServiceEndpoint).AppendLine();

            var descriptor = new SolutionComponentDescriptor(service);

            descriptor.WithUrls          = true;
            descriptor.WithManagedInfo   = true;
            descriptor.WithSolutionsInfo = true;

            var descriptorHandler = new DependencyDescriptionHandler(descriptor);

            var dependencyRepository = new DependencyRepository(service);

            bool isconnectionDataDirty = false;

            List <string> listNotExistsOnDisk        = new List <string>();
            List <string> listNotFoundedInCRMNoLink  = new List <string>();
            List <string> listLastLinkEqualByContent = new List <string>();

            List <SolutionComponent> webResourceNames = new List <SolutionComponent>();

            Dictionary <SolutionComponent, string> webResourceDescriptions = new Dictionary <SolutionComponent, string>();

            WebResourceRepository repositoryWebResource = new WebResourceRepository(service);

            FormatTextTableHandler tableWithoutDependenComponents = new FormatTextTableHandler();

            tableWithoutDependenComponents.SetHeader("FilePath", "Web Resource Name", "Web Resource Type");

            var groups = selectedFiles.GroupBy(sel => sel.Extension);

            foreach (var gr in groups)
            {
                var names = gr.Select(sel => sel.FriendlyFilePath).ToArray();

                var dict = repositoryWebResource.FindMultiple(gr.Key, names);

                foreach (var selectedFile in gr)
                {
                    if (File.Exists(selectedFile.FilePath))
                    {
                        string name = selectedFile.FriendlyFilePath.ToLower();

                        var webresource = WebResourceRepository.FindWebResourceInDictionary(dict, name, gr.Key);

                        if (webresource == null)
                        {
                            Guid?webId = connectionData.GetLastLinkForFile(selectedFile.FriendlyFilePath);

                            if (webId.HasValue)
                            {
                                webresource = await repositoryWebResource.GetByIdAsync(webId.Value);

                                if (webresource != null)
                                {
                                    listLastLinkEqualByContent.Add(selectedFile.FriendlyFilePath);
                                }
                            }
                        }

                        if (webresource != null)
                        {
                            // Запоминается файл
                            isconnectionDataDirty = true;
                            connectionData.AddMapping(webresource.Id, selectedFile.FriendlyFilePath);

                            var coll = await dependencyRepository.GetDependentComponentsAsync((int)ComponentType.WebResource, webresource.Id);

                            var desc = await descriptorHandler.GetDescriptionDependentAsync(coll);

                            if (!string.IsNullOrEmpty(desc))
                            {
                                var component = new SolutionComponent()
                                {
                                    ComponentType = new OptionSetValue((int)ComponentType.WebResource),
                                    ObjectId      = webresource.Id,
                                };

                                webResourceNames.Add(component);

                                webResourceDescriptions.Add(component, desc);
                            }
                            else
                            {
                                tableWithoutDependenComponents.AddLine(selectedFile.FriendlyFilePath, webresource.Name, "'" + webresource.FormattedValues[WebResource.Schema.Attributes.webresourcetype] + "'");
                            }
                        }
                        else
                        {
                            connectionData.RemoveMapping(selectedFile.FriendlyFilePath);

                            listNotFoundedInCRMNoLink.Add(selectedFile.FriendlyFilePath);
                        }
                    }
                    else
                    {
                        listNotExistsOnDisk.Add(selectedFile.FilePath);
                    }
                }
            }

            if (isconnectionDataDirty)
            {
                //Сохранение настроек после публикации
                connectionData.Save();
            }

            FindsController.WriteToContentList(listNotFoundedInCRMNoLink, content, "File NOT FOUNDED in CRM: {0}");

            FindsController.WriteToContentList(listLastLinkEqualByContent, content, "Files NOT FOUNDED in CRM, but has Last Link: {0}");

            FindsController.WriteToContentList(listNotExistsOnDisk, content, Properties.OutputStrings.FileNotExistsFormat1);

            FindsController.WriteToContentList(tableWithoutDependenComponents.GetFormatedLines(true), content, "Files without dependent components: {0}");

            FindsController.WriteToContentDictionary(descriptor, content, webResourceNames, webResourceDescriptions, "WebResource dependent components: {0}");

            commonConfig.CheckFolderForExportExists(this._iWriteToOutput);

            string fileName = string.Format("{0}.WebResourceDependent at {1}.txt", connectionData.Name, DateTime.Now.ToString("yyyy.MM.dd HH-mm-ss"));

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

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

            this._iWriteToOutput.WriteToOutput(connectionData, Properties.OutputStrings.CreatedFileWithWebResourcesDependentComponentsFormat1, filePath);

            this._iWriteToOutput.PerformAction(service.ConnectionData, filePath);
        }
Esempio n. 10
0
        public void GenerateDescription(StringBuilder builder, IEnumerable <SolutionComponent> components, bool withManaged, bool withSolutionInfo, bool withUrls)
        {
            FormatTextTableHandler handler = new FormatTextTableHandler();

            handler.SetHeader(
                "LogicalName"
                , "DisplayName"
                , "Description"
                , "EnablesEntityName"
                , "EnablesAttributeName"
                , "ErrorCode"
                , "EvaluationPriority"
                , "IsPrivate"
                , "IsGlobalForOperation"
                , "ManagedPropertyType"
                , "Operation"
                , "Behavior"
                );

            //public Label Description { get; }
            //public Label DisplayName { get; }
            //public string EnablesAttributeName { get; }
            //public string EnablesEntityName { get; }
            //public int? ErrorCode { get; }
            //public ManagedPropertyEvaluationPriority? EvaluationPriority { get; }
            //public string IntroducedVersion { get; }
            //public bool? IsGlobalForOperation { get; }
            //public bool? IsPrivate { get; }
            //public string LogicalName { get; }
            //public ManagedPropertyType? ManagedPropertyType { get; }
            //public ManagedPropertyOperation? Operation { get; }

            foreach (var comp in components)
            {
                if (this.AllManagedProperties.ContainsKey(comp.ObjectId.Value))
                {
                    var behavior = SolutionComponent.GetRootComponentBehaviorName(comp.RootComponentBehavior?.Value);

                    var managedProperty = this.AllManagedProperties[comp.ObjectId.Value];

                    handler.AddLine(
                        managedProperty.LogicalName
                        , CreateFileHandler.GetLocalizedLabel(managedProperty.DisplayName)
                        , CreateFileHandler.GetLocalizedLabel(managedProperty.Description)
                        , managedProperty.EnablesEntityName
                        , managedProperty.EnablesAttributeName
                        , managedProperty.ErrorCode.ToString()
                        , managedProperty.EvaluationPriority.ToString()
                        , managedProperty.IsPrivate.ToString()
                        , managedProperty.IsGlobalForOperation.ToString()
                        , managedProperty.ManagedPropertyType.ToString()
                        , managedProperty.Operation.ToString()
                        , behavior
                        );
                }
                else
                {
                    handler.AddLine(comp.ObjectId.ToString());
                }
            }

            List <string> lines = handler.GetFormatedLines(true);

            lines.ForEach(item => builder.AppendFormat(formatSpacer, item).AppendLine());
        }
                                          > > FindFilesNotExistsInCrm(
            IWriteToOutput _iWriteToOutput
            , List <SelectedFile> selectedFiles
            , ConnectionData connectionData)
        {
            if (connectionData == null)
            {
                _iWriteToOutput.WriteToOutput(connectionData, Properties.OutputStrings.NoCurrentCRMConnection);
                return(null);
            }

            _iWriteToOutput.WriteToOutput(connectionData, Properties.OutputStrings.ConnectingToCRM);

            _iWriteToOutput.WriteToOutput(connectionData, connectionData.GetConnectionDescription());

            // Подключаемся к CRM.
            var service = await QuickConnection.ConnectAsync(connectionData);

            if (service == null)
            {
                _iWriteToOutput.WriteToOutput(connectionData, Properties.OutputStrings.ConnectionFailedFormat1, connectionData.Name);
                return(null);
            }

            _iWriteToOutput.WriteToOutput(connectionData, Properties.OutputStrings.CurrentServiceEndpointFormat1, service.CurrentServiceEndpoint);

            bool isconnectionDataDirty = false;

            var listNotFoundedInCrmNoLink   = new List <SelectedFile>();
            var listNotFoundedInCrmWithLink = new List <Tuple <SelectedFile, WebResource> >();

            List <string> listNotExistsOnDisk = new List <string>();

            // Репозиторий для работы с веб-ресурсами
            WebResourceRepository webResourceRepository = new WebResourceRepository(service);

            var groups = selectedFiles.GroupBy(sel => sel.Extension);

            foreach (var gr in groups)
            {
                var names = gr.Select(sel => sel.FriendlyFilePath).ToArray();

                var dict = webResourceRepository.FindMultiple(gr.Key, names
                                                              , new ColumnSet(
                                                                  WebResource.Schema.EntityPrimaryIdAttribute
                                                                  , WebResource.Schema.Attributes.name
                                                                  , WebResource.Schema.Attributes.webresourcetype
                                                                  ));

                foreach (var selectedFile in gr)
                {
                    if (!File.Exists(selectedFile.FilePath))
                    {
                        listNotExistsOnDisk.Add(selectedFile.FilePath);
                        continue;
                    }

                    string name = selectedFile.FriendlyFilePath.ToLower();

                    var webresource = WebResourceRepository.FindWebResourceInDictionary(dict, name, gr.Key);

                    if (webresource != null)
                    {
                        // Запоминается файл
                        isconnectionDataDirty = true;
                        connectionData.AddMapping(webresource.Id, selectedFile.FriendlyFilePath);
                    }
                    else
                    {
                        Guid?webId = connectionData.GetLastLinkForFile(selectedFile.FriendlyFilePath);

                        if (webId.HasValue)
                        {
                            webresource = await webResourceRepository.GetByIdAsync(webId.Value, new ColumnSet(true));

                            if (webresource != null)
                            {
                                listNotFoundedInCrmWithLink.Add(Tuple.Create(selectedFile, webresource));

                                isconnectionDataDirty = true;
                                connectionData.AddMapping(webresource.Id, selectedFile.FriendlyFilePath);
                            }
                            else
                            {
                                connectionData.RemoveMapping(selectedFile.FriendlyFilePath);

                                listNotFoundedInCrmNoLink.Add(selectedFile);
                            }
                        }
                        else
                        {
                            listNotFoundedInCrmNoLink.Add(selectedFile);
                        }
                    }
                }
            }

            if (isconnectionDataDirty)
            {
                //Сохранение настроек после публикации
                connectionData.Save();
            }

            var tabSpacer = "    ";

            if (listNotFoundedInCrmNoLink.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File NOT FOUNDED in CRM: {0}", listNotFoundedInCrmNoLink.Count);

                listNotFoundedInCrmNoLink.Sort();

                listNotFoundedInCrmNoLink.ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (listNotFoundedInCrmWithLink.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File NOT FOUNDED in CRM, but has Last Link: {0}", listNotFoundedInCrmWithLink.Count);

                FormatTextTableHandler tableLastLinkDifferent = new FormatTextTableHandler();
                tableLastLinkDifferent.SetHeader("FriendlyFilePath", "WebResourceName");

                listNotFoundedInCrmWithLink.ForEach(i => tableLastLinkDifferent.AddLine(i.Item1.FriendlyFilePath, i.Item2.Name));

                tableLastLinkDifferent.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (listNotExistsOnDisk.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, Properties.OutputStrings.FileNotExistsFormat1, listNotExistsOnDisk.Count);

                listNotExistsOnDisk.Sort();

                listNotExistsOnDisk.ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (listNotFoundedInCrmNoLink.Count + listNotFoundedInCrmWithLink.Count == 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "No files not exists in Crm");
            }

            return(Tuple.Create(service, listNotFoundedInCrmNoLink, listNotFoundedInCrmWithLink));
        }
                                          > > ComparingFilesAndWebResources(
            IWriteToOutput _iWriteToOutput
            , List <SelectedFile> selectedFiles
            , ConnectionData connectionData
            , bool withDetails)
        {
            if (connectionData == null)
            {
                _iWriteToOutput.WriteToOutput(connectionData, Properties.OutputStrings.NoCurrentCRMConnection);
                return(null);
            }

            var dictFilesEqualByTextNotContent = new List <Tuple <SelectedFile, WebResource> >();
            var dictFilesNotEqualByText        = new List <Tuple <SelectedFile, WebResource, ContentCopareResult> >();

            _iWriteToOutput.WriteToOutput(connectionData, Properties.OutputStrings.ConnectingToCRM);

            _iWriteToOutput.WriteToOutput(connectionData, connectionData.GetConnectionDescription());

            // Подключаемся к CRM.
            var service = await QuickConnection.ConnectAsync(connectionData);

            if (service == null)
            {
                _iWriteToOutput.WriteToOutput(connectionData, Properties.OutputStrings.ConnectionFailedFormat1, connectionData.Name);
                return(null);
            }

            _iWriteToOutput.WriteToOutput(connectionData, Properties.OutputStrings.CurrentServiceEndpointFormat1, service.CurrentServiceEndpoint);

            bool isconnectionDataDirty = false;

            List <string> listNotExistsOnDisk = new List <string>();

            List <string> listNotFoundedInCRMNoLink = new List <string>();

            int countEqualByContent = 0;

            FormatTextTableHandler tableEqualByText = new FormatTextTableHandler();

            tableEqualByText.SetHeader("FriendlyFilePath", "WebResourceName");

            FormatTextTableHandler tableDifferent = new FormatTextTableHandler();

            if (withDetails)
            {
                tableDifferent.SetHeader("FriendlyFilePath", "WebResourceName", "+Inserts", "(+Length)", "-Deletes", "(-Length)");
            }
            else
            {
                tableDifferent.SetHeader("FriendlyFilePath", "WebResourceName");
            }

            FormatTextTableHandler tableDifferentOnlyInserts = new FormatTextTableHandler();

            tableDifferentOnlyInserts.SetHeader("FriendlyFilePath", "WebResourceName", "+Inserts", "(+Length)");

            FormatTextTableHandler tableDifferentOnlyDeletes = new FormatTextTableHandler();

            tableDifferentOnlyDeletes.SetHeader("FriendlyFilePath", "WebResourceName", "-Deletes", "(-Length)");

            FormatTextTableHandler tableDifferentComplexChanges = new FormatTextTableHandler();

            tableDifferentComplexChanges.SetHeader("FriendlyFilePath", "WebResourceName", "+Inserts", "(+Length)", "-Deletes", "(-Length)");

            FormatTextTableHandler tableDifferentMirror = new FormatTextTableHandler();

            tableDifferentMirror.SetHeader("FriendlyFilePath", "WebResourceName", "+Inserts", "(+Length)", "-Deletes", "(-Length)");

            FormatTextTableHandler tableDifferentMirrorWithInserts = new FormatTextTableHandler();

            tableDifferentMirrorWithInserts.SetHeader("FriendlyFilePath", "WebResourceName", "+Inserts", "(+Length)", "-Deletes", "(-Length)");

            FormatTextTableHandler tableDifferentMirrorWithDeletes = new FormatTextTableHandler();

            tableDifferentMirrorWithDeletes.SetHeader("FriendlyFilePath", "WebResourceName", "+Inserts", "(+Length)", "-Deletes", "(-Length)");

            FormatTextTableHandler tableLastLinkEqualByContent = new FormatTextTableHandler();

            tableLastLinkEqualByContent.SetHeader("FriendlyFilePath", "WebResourceName");

            FormatTextTableHandler listLastLinkEqualByText = new FormatTextTableHandler();

            listLastLinkEqualByText.SetHeader("FriendlyFilePath", "WebResourceName");

            FormatTextTableHandler tableLastLinkDifferent = new FormatTextTableHandler();

            if (withDetails)
            {
                tableLastLinkDifferent.SetHeader("FriendlyFilePath", "WebResourceName", "+Inserts", "(+Length)", "-Deletes", "(-Length)");
            }
            else
            {
                tableLastLinkDifferent.SetHeader("FriendlyFilePath", "WebResourceName");
            }

            FormatTextTableHandler tableLastLinkDifferentOnlyInserts = new FormatTextTableHandler();

            tableLastLinkDifferentOnlyInserts.SetHeader("FriendlyFilePath", "WebResourceName", "+Inserts", "(+Length)");

            FormatTextTableHandler tableLastLinkDifferentOnlyDeletes = new FormatTextTableHandler();

            tableLastLinkDifferentOnlyDeletes.SetHeader("FriendlyFilePath", "WebResourceName", "-Deletes", "(-Length)");

            FormatTextTableHandler tableLastLinkDifferentComplexChanges = new FormatTextTableHandler();

            tableLastLinkDifferentComplexChanges.SetHeader("FriendlyFilePath", "WebResourceName", "+Inserts", "(+Length)", "-Deletes", "(-Length)");

            FormatTextTableHandler tableLastLinkDifferentMirror = new FormatTextTableHandler();

            tableLastLinkDifferentMirror.SetHeader("FriendlyFilePath", "WebResourceName", "+Inserts", "(+Length)", "-Deletes", "(-Length)");

            FormatTextTableHandler tableLastLinkDifferentMirrorWithInserts = new FormatTextTableHandler();

            tableLastLinkDifferentMirrorWithInserts.SetHeader("FriendlyFilePath", "+Inserts", "(+Length)", "-Deletes", "(-Length)");

            FormatTextTableHandler tableLastLinkDifferentMirrorWithDeletes = new FormatTextTableHandler();

            tableLastLinkDifferentMirrorWithDeletes.SetHeader("FriendlyFilePath", "WebResourceName", "+Inserts", "(+Length)", "-Deletes", "(-Length)");

            // Репозиторий для работы с веб-ресурсами
            WebResourceRepository webResourceRepository = new WebResourceRepository(service);

            var groups = selectedFiles.GroupBy(sel => sel.Extension);

            foreach (var gr in groups)
            {
                var names = gr.Select(sel => sel.FriendlyFilePath).ToArray();

                var dict = webResourceRepository.FindMultiple(gr.Key, names
                                                              , new ColumnSet(
                                                                  WebResource.Schema.EntityPrimaryIdAttribute
                                                                  , WebResource.Schema.Attributes.name
                                                                  , WebResource.Schema.Attributes.webresourcetype
                                                                  , WebResource.Schema.Attributes.content
                                                                  ));

                foreach (var selectedFile in gr)
                {
                    if (!File.Exists(selectedFile.FilePath))
                    {
                        listNotExistsOnDisk.Add(selectedFile.FilePath);
                        continue;
                    }

                    string urlShowDifference = string.Format("{0}:///{1}?ConnectionId={2}", UrlCommandFilter.PrefixShowDifference, selectedFile.FilePath.Replace('\\', '/'), connectionData.ConnectionId.ToString());

                    string name = selectedFile.FriendlyFilePath.ToLower();

                    var webresource = WebResourceRepository.FindWebResourceInDictionary(dict, name, gr.Key);

                    if (webresource != null)
                    {
                        // Запоминается файл
                        isconnectionDataDirty = true;
                        connectionData.AddMapping(webresource.Id, selectedFile.FriendlyFilePath);

                        var contentWebResource = webresource.Content ?? string.Empty;

                        var arrayFile = File.ReadAllBytes(selectedFile.FilePath);

                        var contentFile = Convert.ToBase64String(arrayFile);

                        if (string.Equals(contentFile, contentWebResource))
                        {
                            countEqualByContent++;
                        }
                        else
                        {
                            var arrayWebResource = Convert.FromBase64String(contentWebResource);

                            var nameWebResource = webresource.Name;

                            var compare = ContentCoparerHelper.CompareByteArrays(selectedFile.Extension, arrayFile, arrayWebResource, withDetails);

                            if (compare.IsEqual)
                            {
                                tableEqualByText.AddLine(selectedFile.UrlFriendlyFilePath, nameWebResource);

                                dictFilesEqualByTextNotContent.Add(Tuple.Create(selectedFile, webresource));
                            }
                            else
                            {
                                dictFilesNotEqualByText.Add(Tuple.Create(selectedFile, webresource, compare));

                                if (withDetails)
                                {
                                    string[] values = new string[]
                                    {
                                        selectedFile.UrlFriendlyFilePath, nameWebResource
                                        , string.Format("+{0}", compare.Inserts)
                                        , string.Format("(+{0})", compare.InsertLength)
                                        , string.Format("-{0}", compare.Deletes)
                                        , string.Format("(-{0})", compare.DeleteLength)
                                        , urlShowDifference
                                    };

                                    tableDifferent.AddLine(values);

                                    if (compare.IsOnlyInserts)
                                    {
                                        tableDifferentOnlyInserts.AddLine(selectedFile.UrlFriendlyFilePath
                                                                          , string.Format("+{0}", compare.Inserts)
                                                                          , string.Format("(+{0})", compare.InsertLength)
                                                                          , urlShowDifference
                                                                          );
                                    }

                                    if (compare.IsOnlyDeletes)
                                    {
                                        tableDifferentOnlyDeletes.AddLine(selectedFile.UrlFriendlyFilePath
                                                                          , string.Format("-{0}", compare.Deletes)
                                                                          , string.Format("(-{0})", compare.DeleteLength)
                                                                          , urlShowDifference
                                                                          );
                                    }

                                    if (compare.IsComplexChanges)
                                    {
                                        tableDifferentComplexChanges.AddLine(values);
                                    }

                                    if (compare.IsMirror)
                                    {
                                        tableDifferentMirror.AddLine(values);
                                    }

                                    if (compare.IsMirrorWithInserts)
                                    {
                                        tableDifferentMirrorWithInserts.AddLine(values);
                                    }

                                    if (compare.IsMirrorWithDeletes)
                                    {
                                        tableDifferentMirrorWithDeletes.AddLine(values);
                                    }
                                }
                                else
                                {
                                    tableDifferent.AddLine(selectedFile.UrlFriendlyFilePath, nameWebResource, urlShowDifference);
                                }
                            }
                        }
                    }
                    else
                    {
                        Guid?webId = connectionData.GetLastLinkForFile(selectedFile.FriendlyFilePath);

                        if (webId.HasValue)
                        {
                            webresource = await webResourceRepository.GetByIdAsync(webId.Value);

                            if (webresource != null)
                            {
                                // Запоминается файл
                                isconnectionDataDirty = true;
                                connectionData.AddMapping(webresource.Id, selectedFile.FriendlyFilePath);

                                var contentWebResource = webresource.Content ?? string.Empty;
                                var nameWebResource    = webresource.Name;

                                var arrayFile = File.ReadAllBytes(selectedFile.FilePath);

                                var contentFile = Convert.ToBase64String(arrayFile);

                                if (string.Equals(contentFile, contentWebResource))
                                {
                                    tableLastLinkEqualByContent.AddLine(selectedFile.UrlFriendlyFilePath, nameWebResource);
                                }
                                else
                                {
                                    var arrayWebResource = Convert.FromBase64String(contentWebResource);

                                    var compare = ContentCoparerHelper.CompareByteArrays(selectedFile.Extension, arrayFile, arrayWebResource);

                                    if (compare.IsEqual)
                                    {
                                        listLastLinkEqualByText.AddLine(selectedFile.UrlFriendlyFilePath, nameWebResource);

                                        dictFilesEqualByTextNotContent.Add(Tuple.Create(selectedFile, webresource));
                                    }
                                    else
                                    {
                                        dictFilesNotEqualByText.Add(Tuple.Create(selectedFile, webresource, compare));

                                        if (withDetails)
                                        {
                                            string[] values = new string[]
                                            {
                                                selectedFile.UrlFriendlyFilePath, nameWebResource
                                                , string.Format("+{0}", compare.Inserts)
                                                , string.Format("(+{0})", compare.InsertLength)
                                                , string.Format("-{0}", compare.Deletes)
                                                , string.Format("(-{0})", compare.DeleteLength)
                                                , urlShowDifference
                                            };

                                            tableLastLinkDifferent.AddLine(values);


                                            if (compare.IsOnlyInserts)
                                            {
                                                tableLastLinkDifferentOnlyInserts.AddLine(selectedFile.UrlFriendlyFilePath, nameWebResource
                                                                                          , string.Format("+{0}", compare.Inserts)
                                                                                          , string.Format("(+{0})", compare.InsertLength)
                                                                                          , urlShowDifference
                                                                                          );
                                            }

                                            if (compare.IsOnlyDeletes)
                                            {
                                                tableLastLinkDifferentOnlyDeletes.AddLine(selectedFile.UrlFriendlyFilePath, nameWebResource
                                                                                          , string.Format("-{0}", compare.Deletes)
                                                                                          , string.Format("(-{0})", compare.DeleteLength)
                                                                                          , urlShowDifference
                                                                                          );
                                            }

                                            if (compare.IsComplexChanges)
                                            {
                                                tableLastLinkDifferentComplexChanges.AddLine(values);
                                            }

                                            if (compare.IsMirror)
                                            {
                                                tableLastLinkDifferentMirror.AddLine(values);
                                            }

                                            if (compare.IsMirrorWithInserts)
                                            {
                                                tableLastLinkDifferentMirrorWithInserts.AddLine(values);
                                            }

                                            if (compare.IsMirrorWithDeletes)
                                            {
                                                tableLastLinkDifferentMirrorWithDeletes.AddLine(values);
                                            }
                                        }
                                        else
                                        {
                                            tableLastLinkDifferent.AddLine(selectedFile.UrlFriendlyFilePath, nameWebResource, urlShowDifference);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                connectionData.RemoveMapping(selectedFile.FriendlyFilePath);

                                listNotFoundedInCRMNoLink.Add(selectedFile.UrlFriendlyFilePath);
                            }
                        }
                        else
                        {
                            listNotFoundedInCRMNoLink.Add(selectedFile.UrlFriendlyFilePath);
                        }
                    }
                }
            }

            if (isconnectionDataDirty)
            {
                //Сохранение настроек после публикации
                connectionData.Save();
            }

            var tabSpacer = "    ";

            if (tableDifferent.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File and web-resource are DIFFERENT by content: {0}", tableDifferent.Count);

                tableDifferent.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableDifferentOnlyInserts.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File and web-resource are DIFFERENT by content WITH ONLY INSERTS: {0}", tableDifferentOnlyInserts.Count);

                tableDifferentOnlyInserts.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableDifferentOnlyDeletes.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File and web-resource are DIFFERENT by content WITH ONLY DELETES: {0}", tableDifferentOnlyDeletes.Count);

                tableDifferentOnlyDeletes.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableDifferentComplexChanges.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File and web-resource are DIFFERENT by content WITH COMPLEX CHANGES: {0}", tableDifferentComplexChanges.Count);

                tableDifferentComplexChanges.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableDifferentMirror.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File and web-resource are DIFFERENT by content WITH MIRROR CHANGES: {0}", tableDifferentMirror.Count);

                tableDifferentMirror.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableDifferentMirrorWithInserts.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File and web-resource are DIFFERENT by content WITH MIRROR CHANGES AND INSERTS: {0}", tableDifferentMirrorWithInserts.Count);

                tableDifferentMirrorWithInserts.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableDifferentMirrorWithDeletes.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File and web-resource are DIFFERENT by content WITH MIRROR CHANGES AND DELETES: {0}", tableDifferentMirrorWithDeletes.Count);

                tableDifferentMirrorWithDeletes.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (listNotFoundedInCRMNoLink.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File NOT FOUNDED in CRM: {0}", listNotFoundedInCRMNoLink.Count);

                listNotFoundedInCRMNoLink.Sort();

                listNotFoundedInCRMNoLink.ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableLastLinkDifferent.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File NOT FOUNDED in CRM, but has Last Link, files DIFFERENT: {0}", tableLastLinkDifferent.Count);

                tableLastLinkDifferent.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }


            if (tableLastLinkDifferentOnlyInserts.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File NOT FOUNDED in CRM, but has Last Link, files DIFFERENT WITH ONLY INSERTS: {0}", tableLastLinkDifferentOnlyInserts.Count);

                tableLastLinkDifferentOnlyInserts.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableLastLinkDifferentOnlyDeletes.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File NOT FOUNDED in CRM, but has Last Link, files DIFFERENT WITH ONLY DELETES: {0}", tableLastLinkDifferentOnlyDeletes.Count);

                tableLastLinkDifferentOnlyDeletes.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableLastLinkDifferentComplexChanges.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File NOT FOUNDED in CRM, but has Last Link, files DIFFERENT WITH COMPLEX CHANGES: {0}", tableLastLinkDifferentComplexChanges.Count);

                tableLastLinkDifferentComplexChanges.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableLastLinkDifferentMirror.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File NOT FOUNDED in CRM, but has Last Link, files DIFFERENT WITH MIRROR CHANGES: {0}", tableLastLinkDifferentMirror.Count);

                tableLastLinkDifferentMirror.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableLastLinkDifferentMirrorWithInserts.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File NOT FOUNDED in CRM, but has Last Link, files DIFFERENT WITH MIRROR CHANGES AND INSERTS: {0}", tableLastLinkDifferentMirrorWithInserts.Count);

                tableLastLinkDifferentMirrorWithInserts.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableLastLinkDifferentMirrorWithDeletes.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File NOT FOUNDED in CRM, but has Last Link, files DIFFERENT WITH MIRROR CHANGES AND DELETES: {0}", tableLastLinkDifferentMirrorWithDeletes.Count);

                tableLastLinkDifferentMirrorWithDeletes.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (listLastLinkEqualByText.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File NOT FOUNDED in CRM, but has Last Link, files EQUALS BY TEXT: {0}", listLastLinkEqualByText.Count);

                listLastLinkEqualByText.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableLastLinkEqualByContent.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File NOT FOUNDED in CRM, but has Last Link, files EQUALS BY CONTENT: {0}", tableLastLinkEqualByContent.Count);

                tableLastLinkEqualByContent.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (listNotExistsOnDisk.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, Properties.OutputStrings.FileNotExistsFormat1, listNotExistsOnDisk.Count);

                listNotExistsOnDisk.Sort();

                listNotExistsOnDisk.ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (tableEqualByText.Count > 0)
            {
                _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                _iWriteToOutput.WriteToOutput(connectionData, "File and web-resource EQUALS BY TEXT: {0}", tableEqualByText.Count);

                tableEqualByText.GetFormatedLines(true).ForEach(item => _iWriteToOutput.WriteToOutput(connectionData, tabSpacer + item));
            }

            if (countEqualByContent > 0)
            {
                if (countEqualByContent == selectedFiles.Count)
                {
                    _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                    _iWriteToOutput.WriteToOutput(connectionData, "All files and web-resources EQUALS BY CONTENT: {0}", countEqualByContent);
                }
                else
                {
                    _iWriteToOutput.WriteToOutput(connectionData, string.Empty);
                    _iWriteToOutput.WriteToOutput(connectionData, "File and web-resource EQUALS BY CONTENT: {0}", countEqualByContent);
                }
            }

            return(Tuple.Create(service, dictFilesEqualByTextNotContent, dictFilesNotEqualByText));
        }
        public void GenerateDescription(StringBuilder builder, IEnumerable <SolutionComponent> components, bool withManaged, bool withSolutionInfo, bool withUrls)
        {
            FormatTextTableHandler handlerUnknowed = new FormatTextTableHandler();

            FormatTextTableHandler handler = new FormatTextTableHandler();

            handler.SetHeader("OptionSetName", "IsCustomizable", "Behavior");

            if (withManaged)
            {
                handler.AppendHeader("IsManaged");
            }

            if (withUrls)
            {
                handler.AppendHeader("Url");
            }

            foreach (var comp in components)
            {
                string behavior = SolutionComponent.GetRootComponentBehaviorName(comp.RootComponentBehavior?.Value);

                if (this._source.AllOptionSetMetadata.ContainsKey(comp.ObjectId.Value))
                {
                    var optionSet = this._source.AllOptionSetMetadata[comp.ObjectId.Value];

                    List <string> values = new List <string>();

                    values.AddRange(new[]
                    {
                        optionSet.Name
                        , optionSet.IsCustomizable?.Value.ToString()
                        , behavior
                    });

                    if (withManaged)
                    {
                        values.Add(optionSet.IsManaged.ToString());
                    }

                    if (withUrls)
                    {
                        values.Add(_source.Service.ConnectionData?.GetGlobalOptionSetUrl(optionSet.MetadataId.Value));
                    }

                    handler.AddLine(values);
                }
                else
                {
                    handlerUnknowed.AddLine(comp.ObjectId.ToString(), behavior);
                }
            }

            if (handlerUnknowed.Count > 0)
            {
                List <string> lines = handlerUnknowed.GetFormatedLines(true);
                builder.AppendFormat(formatSpacer, unknowedMessage).AppendLine();
                lines.ForEach(item => builder.AppendFormat(formatSpacer, item).AppendLine());
            }

            {
                List <string> lines = handler.GetFormatedLines(true);

                lines.ForEach(item => builder.AppendFormat(formatSpacer, item).AppendLine());
            }
        }
        public string GenerateDescriptionSingle(SolutionComponent solutionComponent, bool withManaged, bool withSolutionInfo, bool withUrls)
        {
            RelationshipMetadataBase metaData = _source.GetRelationshipMetadata(solutionComponent.ObjectId.Value);

            if (metaData != null)
            {
                string behavior = SolutionComponent.GetRootComponentBehaviorName(solutionComponent.RootComponentBehavior?.Value);

                if (metaData is OneToManyRelationshipMetadata)
                {
                    FormatTextTableHandler handlerManyToOne = new FormatTextTableHandler();
                    handlerManyToOne.SetHeader("ReferencingAttribute", "Type", "ReferencedEntity", "SchemaName", "Behavior", "IsCustomizable");

                    if (withManaged)
                    {
                        handlerManyToOne.AppendHeader("IsManaged");
                    }

                    if (withUrls)
                    {
                        handlerManyToOne.AppendHeader("Url");
                    }

                    var relationship = metaData as OneToManyRelationshipMetadata;

                    List <string> values = new List <string>();

                    values.AddRange(new[]
                    {
                        string.Format("{0}.{1}", relationship.ReferencingEntity, relationship.ReferencingAttribute)
                        , "Many to One"
                        , relationship.ReferencedEntity
                        , relationship.SchemaName
                        , behavior
                        , relationship.IsCustomizable?.Value.ToString()
                    });

                    if (withManaged)
                    {
                        values.Add(metaData.IsManaged.ToString());
                    }

                    if (withUrls)
                    {
                        var entityMetadata = _source.GetEntityMetadata(relationship.ReferencedEntity);
                        if (entityMetadata != null)
                        {
                            values.Add(_source.Service.ConnectionData?.GetRelationshipMetadataRelativeUrl(entityMetadata.MetadataId.Value, relationship.MetadataId.Value));
                        }
                    }

                    handlerManyToOne.AddLine(values);

                    var str = handlerManyToOne.GetFormatedLinesWithHeadersInLine(false).FirstOrDefault();

                    return(string.Format("{0} {1}", this.ComponentTypeEnum.ToString(), str));
                }
                else if (metaData is ManyToManyRelationshipMetadata)
                {
                    FormatTextTableHandler handlerManyToMany = new FormatTextTableHandler();
                    handlerManyToMany.SetHeader("Entity - Entity", "Type", "SchemaName", "Behavior", "IsCustomizable");

                    if (withManaged)
                    {
                        handlerManyToMany.AppendHeader("IsManaged");
                    }

                    if (withUrls)
                    {
                        handlerManyToMany.AppendHeader("Url");
                    }

                    var relationship = metaData as ManyToManyRelationshipMetadata;

                    List <string> values = new List <string>();

                    values.AddRange(new[]
                    {
                        string.Format("{0} - {1}", relationship.Entity1LogicalName, relationship.Entity2LogicalName)
                        , "Many to Many"
                        , relationship.SchemaName
                        , behavior
                        , relationship.IsCustomizable?.Value.ToString()
                    });

                    if (withManaged)
                    {
                        values.Add(metaData.IsManaged.ToString());
                    }

                    if (withUrls)
                    {
                        var entityMetadata = _source.GetEntityMetadata(relationship.Entity1LogicalName);
                        if (entityMetadata != null)
                        {
                            values.Add(_source.Service.ConnectionData?.GetRelationshipMetadataRelativeUrl(entityMetadata.MetadataId.Value, relationship.MetadataId.Value));
                        }
                    }

                    handlerManyToMany.AddLine(values);

                    var str = handlerManyToMany.GetFormatedLinesWithHeadersInLine(false).FirstOrDefault();

                    return(string.Format("{0} {1}", this.ComponentTypeEnum.ToString(), str));
                }
            }

            return(solutionComponent.ToString());
        }
        public void GenerateDescription(StringBuilder builder, IEnumerable <SolutionComponent> components, bool withManaged, bool withSolutionInfo, bool withUrls)
        {
            FormatTextTableHandler handler = new FormatTextTableHandler();

            FormatTextTableHandler handlerManyToOne = new FormatTextTableHandler();

            handlerManyToOne.SetHeader("ReferencingAttribute", "Type", "ReferencedEntity", "SchemaName", "IsCustomizable", "Behavior");

            FormatTextTableHandler handlerManyToMany = new FormatTextTableHandler();

            handlerManyToMany.SetHeader("Entity - Entity", "Type", "SchemaName", "IsCustomizable", "Behavior");

            if (withManaged)
            {
                handlerManyToOne.AppendHeader("IsManaged");
                handlerManyToMany.AppendHeader("IsManaged");
            }

            if (withUrls)
            {
                handlerManyToOne.AppendHeader("Url");
                handlerManyToMany.AppendHeader("Url");
            }

            foreach (var comp in components)
            {
                RelationshipMetadataBase metaData = _source.GetRelationshipMetadata(comp.ObjectId.GetValueOrDefault());

                string behavior = SolutionComponent.GetRootComponentBehaviorName(comp.RootComponentBehavior?.Value);

                if (metaData != null)
                {
                    if (metaData is OneToManyRelationshipMetadata)
                    {
                        var relationship = metaData as OneToManyRelationshipMetadata;

                        List <string> values = new List <string>();

                        values.AddRange(new[]
                        {
                            string.Format("{0}.{1}", relationship.ReferencingEntity, relationship.ReferencingAttribute)
                            , "Many to One"
                            , relationship.ReferencedEntity
                            , relationship.SchemaName
                            , (relationship.IsCustomizable?.Value).GetValueOrDefault().ToString()
                            , behavior
                        });

                        if (withManaged)
                        {
                            values.Add(metaData.IsManaged.ToString());
                        }

                        if (withUrls)
                        {
                            var entityMetadata = _source.GetEntityMetadata(relationship.ReferencedEntity);
                            if (entityMetadata != null)
                            {
                                values.Add(_source.Service.ConnectionData?.GetRelationshipMetadataUrl(entityMetadata.MetadataId.Value, relationship.MetadataId.Value));
                            }
                        }

                        handlerManyToOne.AddLine(values);
                    }
                    else if (metaData is ManyToManyRelationshipMetadata)
                    {
                        var relationship = metaData as ManyToManyRelationshipMetadata;

                        List <string> values = new List <string>();

                        values.AddRange(new[]
                        {
                            string.Format("{0} - {1}", relationship.Entity1LogicalName, relationship.Entity2LogicalName)
                            , "Many to Many"
                            , relationship.SchemaName
                            , behavior
                            , (relationship.IsCustomizable?.Value).GetValueOrDefault().ToString()
                        });

                        if (withManaged)
                        {
                            values.Add(metaData.IsManaged.ToString());
                        }

                        if (withUrls)
                        {
                            var entityMetadata = _source.GetEntityMetadata(relationship.Entity1LogicalName);
                            if (entityMetadata != null)
                            {
                                values.Add(_source.Service.ConnectionData?.GetRelationshipMetadataUrl(entityMetadata.MetadataId.Value, relationship.MetadataId.Value));
                            }
                        }

                        handlerManyToMany.AddLine(values);
                    }
                }
                else
                {
                    handler.AddLine(comp.ObjectId.ToString(), behavior);
                }
            }

            List <string> linesUnknowed = handler.GetFormatedLines(true);

            List <string> linesOne = handlerManyToOne.GetFormatedLines(true);

            List <string> linesMany = handlerManyToMany.GetFormatedLines(true);

            if (linesUnknowed.Any())
            {
                builder.AppendFormat(formatSpacer, unknowedMessage).AppendLine();
                linesUnknowed.ForEach(item => builder.AppendFormat(formatSpacer, item).AppendLine());
            }

            linesOne.ForEach(item => builder.AppendFormat(formatSpacer, item).AppendLine());
            linesMany.ForEach(item => builder.AppendFormat(formatSpacer, item).AppendLine());
        }