public abstract SyntaxNode ChangeSignature(
     Document document,
     ISymbol declarationSymbol,
     SyntaxNode potentiallyUpdatedNode,
     SyntaxNode originalNode,
     SignatureChange signaturePermutation,
     CancellationToken cancellationToken);
 public abstract SyntaxNode ChangeSignature(
     Document document,
     ISymbol declarationSymbol,
     SyntaxNode potentiallyUpdatedNode,
     SyntaxNode originalNode,
     SignatureChange signaturePermutation,
     CancellationToken cancellationToken);
        private static SignatureChange CreateCompensatingSignatureChange(ISymbol declarationSymbol, SignatureChange updatedSignature)
        {
            if (declarationSymbol.GetParameters().Length > updatedSignature.OriginalConfiguration.ToListOfParameters().Count)
            {
                var origStuff = updatedSignature.OriginalConfiguration.ToListOfParameters();
                var newStuff  = updatedSignature.UpdatedConfiguration.ToListOfParameters();

                var realStuff = declarationSymbol.GetParameters();

                var bonusParameters = realStuff.Skip(origStuff.Count);

                origStuff.AddRange(bonusParameters);
                newStuff.AddRange(bonusParameters);

                var newOrigParams    = ParameterConfiguration.Create(origStuff, updatedSignature.OriginalConfiguration.ThisParameter != null);
                var newUpdatedParams = ParameterConfiguration.Create(newStuff, updatedSignature.OriginalConfiguration.ThisParameter != null);
                updatedSignature = new SignatureChange(newOrigParams, newUpdatedParams);
            }

            return(updatedSignature);
        }
        protected static List <IUnifiedArgumentSyntax> PermuteArguments(
            Document document,
            ISymbol declarationSymbol,
            List <IUnifiedArgumentSyntax> arguments,
            SignatureChange updatedSignature,
            bool isReducedExtensionMethod = false)
        {
            // 1. Determine which parameters are permutable

            var declarationParameters          = declarationSymbol.GetParameters().ToList();
            var declarationParametersToPermute = GetParametersToPermute(arguments, declarationParameters, isReducedExtensionMethod);
            var argumentsToPermute             = arguments.Take(declarationParametersToPermute.Count).ToList();

            // 2. Create an argument to parameter map, and a parameter to index map for the sort.
            var argumentToParameterMap = new Dictionary <IUnifiedArgumentSyntax, IParameterSymbol>();
            var parameterToIndexMap    = new Dictionary <IParameterSymbol, int>();

            for (int i = 0; i < declarationParametersToPermute.Count; i++)
            {
                var decl = declarationParametersToPermute[i];
                var arg  = argumentsToPermute[i];

                argumentToParameterMap[arg] = decl;
                var originalIndex = declarationParameters.IndexOf(decl);

                var updatedIndex = updatedSignature.GetUpdatedIndex(originalIndex);

                // If there's no value, then we may be handling a method with more parameters than the original symbol (like BeginInvoke).
                parameterToIndexMap[decl] = updatedIndex.HasValue ? updatedIndex.Value : -1;
            }

            // 3. Sort the arguments that need to be reordered

            argumentsToPermute.Sort((a1, a2) => { return(parameterToIndexMap[argumentToParameterMap[a1]].CompareTo(parameterToIndexMap[argumentToParameterMap[a2]])); });

            // 4. Add names to arguments where necessary.

            var  newArguments      = new List <IUnifiedArgumentSyntax>();
            int  expectedIndex     = 0 + (isReducedExtensionMethod ? 1 : 0);
            bool seenNamedArgument = false;

            foreach (var argument in argumentsToPermute)
            {
                var param       = argumentToParameterMap[argument];
                var actualIndex = updatedSignature.GetUpdatedIndex(declarationParameters.IndexOf(param));

                if (!actualIndex.HasValue)
                {
                    continue;
                }

                if ((seenNamedArgument || actualIndex != expectedIndex) && !argument.IsNamed)
                {
                    newArguments.Add(argument.WithName(param.Name).WithAdditionalAnnotations(Formatter.Annotation));
                    seenNamedArgument = true;
                }
                else
                {
                    newArguments.Add(argument);
                }

                seenNamedArgument |= argument.IsNamed;
                expectedIndex++;
            }

            // 5. Add the remaining arguments. These will already have names or be params arguments, but may have been removed.

            bool removedParams = updatedSignature.OriginalConfiguration.ParamsParameter != null && updatedSignature.UpdatedConfiguration.ParamsParameter == null;

            for (int i = declarationParametersToPermute.Count; i < arguments.Count; i++)
            {
                if (!arguments[i].IsNamed && removedParams && i >= updatedSignature.UpdatedConfiguration.ToListOfParameters().Count)
                {
                    break;
                }

                if (!arguments[i].IsNamed || updatedSignature.UpdatedConfiguration.ToListOfParameters().Any(p => p.Name == arguments[i].GetName()))
                {
                    newArguments.Add(arguments[i]);
                }
            }

            return(newArguments);
        }
        private static SignatureChange CreateCompensatingSignatureChange(ISymbol declarationSymbol, SignatureChange updatedSignature)
        {
            if (declarationSymbol.GetParameters().Count() > updatedSignature.OriginalConfiguration.ToListOfParameters().Count)
            {
                var origStuff = updatedSignature.OriginalConfiguration.ToListOfParameters();
                var newStuff = updatedSignature.UpdatedConfiguration.ToListOfParameters();

                var realStuff = declarationSymbol.GetParameters();

                var bonusParameters = realStuff.Skip(origStuff.Count);

                origStuff.AddRange(bonusParameters);
                newStuff.AddRange(bonusParameters);

                var newOrigParams = ParameterConfiguration.Create(origStuff, updatedSignature.OriginalConfiguration.ThisParameter != null);
                var newUpdatedParams = ParameterConfiguration.Create(newStuff, updatedSignature.OriginalConfiguration.ThisParameter != null);
                updatedSignature = new SignatureChange(newOrigParams, newUpdatedParams);
            }

            return updatedSignature;
        }
        protected static List<IUnifiedArgumentSyntax> PermuteArguments(
            Document document,
            ISymbol declarationSymbol,
            List<IUnifiedArgumentSyntax> arguments,
            SignatureChange updatedSignature,
            bool isReducedExtensionMethod = false)
        {
            // 1. Determine which parameters are permutable

            var declarationParameters = declarationSymbol.GetParameters().ToList();
            var declarationParametersToPermute = GetParametersToPermute(arguments, declarationParameters, isReducedExtensionMethod);
            var argumentsToPermute = arguments.Take(declarationParametersToPermute.Count).ToList();

            // 2. Create an argument to parameter map, and a parameter to index map for the sort.
            var argumentToParameterMap = new Dictionary<IUnifiedArgumentSyntax, IParameterSymbol>();
            var parameterToIndexMap = new Dictionary<IParameterSymbol, int>();

            for (int i = 0; i < declarationParametersToPermute.Count; i++)
            {
                var decl = declarationParametersToPermute[i];
                var arg = argumentsToPermute[i];

                argumentToParameterMap[arg] = decl;
                var originalIndex = declarationParameters.IndexOf(decl);

                var updatedIndex = updatedSignature.GetUpdatedIndex(originalIndex);

                // If there's no value, then we may be handling a method with more parameters than the original symbol (like BeginInvoke).
                parameterToIndexMap[decl] = updatedIndex.HasValue ? updatedIndex.Value : -1;
            }

            // 3. Sort the arguments that need to be reordered

            argumentsToPermute.Sort((a1, a2) => { return parameterToIndexMap[argumentToParameterMap[a1]].CompareTo(parameterToIndexMap[argumentToParameterMap[a2]]); });

            // 4. Add names to arguments where necessary.

            var newArguments = new List<IUnifiedArgumentSyntax>();
            int expectedIndex = 0 + (isReducedExtensionMethod ? 1 : 0);
            bool seenNamedArgument = false;

            foreach (var argument in argumentsToPermute)
            {
                var param = argumentToParameterMap[argument];
                var actualIndex = updatedSignature.GetUpdatedIndex(declarationParameters.IndexOf(param));

                if (!actualIndex.HasValue)
                {
                    continue;
                }

                if ((seenNamedArgument || actualIndex != expectedIndex) && !argument.IsNamed)
                {
                    newArguments.Add(argument.WithName(param.Name).WithAdditionalAnnotations(Formatter.Annotation));
                    seenNamedArgument = true;
                }
                else
                {
                    newArguments.Add(argument);
                }

                seenNamedArgument |= argument.IsNamed;
                expectedIndex++;
            }

            // 5. Add the remaining arguments. These will already have names or be params arguments, but may have been removed.

            bool removedParams = updatedSignature.OriginalConfiguration.ParamsParameter != null && updatedSignature.UpdatedConfiguration.ParamsParameter == null;

            for (int i = declarationParametersToPermute.Count; i < arguments.Count; i++)
            {
                if (!arguments[i].IsNamed && removedParams && i >= updatedSignature.UpdatedConfiguration.ToListOfParameters().Count)
                {
                    break;
                }

                if (!arguments[i].IsNamed || updatedSignature.UpdatedConfiguration.ToListOfParameters().Any(p => p.Name == arguments[i].GetName()))
                {
                    newArguments.Add(arguments[i]);
                }
            }

            return newArguments;
        }