public async Task ApplyRefactoring(Solution solution)
        {
            try
            {
                ReadUserInput();

                documentsRegistry = await InitializeDocumentRegistry(solution);

                invokedMethodDocument = await GetInvokationMethodType(solution);

                documentsToCopy.Add(invokedMethodDocument);

                await RecursiveMethod(invokedMethodDocument);

                var invokedMethodProjectName = invokedMethodDocument.DocumentTypeFullName.Split('.').FirstOrDefault();

                startup = documentsRegistry.FirstOrDefault(x => x.DocumentTypeFullName.Contains(invokedMethodProjectName + ".Startup"));

                CreateMicroserviceDirectory();

                BeginWriting();
            }
            catch (Exception)
            {
                Console.WriteLine("There was an error applying the refactoring.");
                Environment.Exit(0);
            }
        }
        private async Task RecursiveMethod(DocumentAnalyzerAggregate document)
        {
            var treeRoot = await document.SyntaxTree.GetRootAsync();

            // We're assuming only one class per file.
            var isClass = treeRoot.DescendantNodes().OfType <ClassDeclarationSyntax>().FirstOrDefault() != null;

            var isInterface = treeRoot.DescendantNodes().OfType <InterfaceDeclarationSyntax>().FirstOrDefault() != null;

            if (isClass)
            {
                await FindTypeDependenciesForType(document);
            }
            else if (isInterface)
            {
                var interfaceImplementations = await GetInterfaceImplementations(document);

                foreach (var interfaceImplementation in interfaceImplementations)
                {
                    if (!documentsToCopy.Contains(interfaceImplementation))
                    {
                        documentsToCopy.Add(interfaceImplementation);

                        await FindTypeDependenciesForType(interfaceImplementation);
                    }
                }
            }
        }
        private async Task FindTypeDependenciesForType(DocumentAnalyzerAggregate document)
        {
            var root = await document.SyntaxTree.GetRootAsync();

            var classDeclaration = root.DescendantNodes().OfType <ClassDeclarationSyntax>().FirstOrDefault();

            foreach (var item in classDeclaration.DescendantNodes())
            {
                string typeName = null;

                if (classDeclaration != null)
                {
                    switch (item)
                    {
                    case SimpleBaseTypeSyntax simpleBaseTypeSyntax:
                        typeName = simpleBaseTypeSyntax.Type.ToString();
                        break;

                    case ParameterSyntax parameterSyntax:
                        typeName = parameterSyntax.Type.ToString();
                        break;

                    case IdentifierNameSyntax identifierNameSyntax:
                        typeName = identifierNameSyntax.ToString();
                        break;

                    case SimpleNameSyntax simpleNameSyntax:
                        typeName = simpleNameSyntax.ToString();
                        break;

                    case TypeSyntax typeSyntax:
                        typeName = typeSyntax.ToString();
                        break;
                    }

                    if (typeName != null)
                    {
                        var documentToCopy = documentsRegistry.FirstOrDefault(x => x.DocumentTypeFullName.Contains(typeName));

                        if (documentToCopy != null && !documentsToCopy.Contains(documentToCopy))
                        {
                            documentsToCopy.Add(documentToCopy);

                            await RecursiveMethod(documentToCopy);
                        }
                    }
                }
            }
        }
        private async Task <HashSet <DocumentAnalyzerAggregate> > GetInterfaceImplementations(DocumentAnalyzerAggregate interfaceDocument)
        {
            var implementations = new HashSet <DocumentAnalyzerAggregate>();

            foreach (var document in documentsRegistry)
            {
                var root = await document.SyntaxTree.GetRootAsync();

                // We only care about classes implementing interfaces and not interfaces implementing interfaces.
                var classDeclaration = root.DescendantNodes().OfType <ClassDeclarationSyntax>().FirstOrDefault();

                if (classDeclaration != null)
                {
                    var name = interfaceDocument.Document.Name.Split('.')[0];

                    var documentLines = classDeclaration.ToString().Split('\n');

                    var classDeclarationLine = documentLines.FirstOrDefault(x => x.Contains(name));

                    if (classDeclarationLine != null)
                    {
                        var classExtensions = classDeclarationLine.Split(':');

                        if (classExtensions.Length > 1)
                        {
                            var classExtensionsList = classExtensions[1].Split(',');

                            if (classExtensionsList.FirstOrDefault(x => x.Contains(name)) != null)
                            {
                                implementations.Add(document);
                            }
                        }
                    }
                }
            }

            return(implementations);
        }