public void AllPossiblePermutationsOfMultipleLiterals()
        {
            const string codeText = @"void Target() { foo(7, 7, 8, 8); }";
            var target = AstMatchHelper.ParseToMethodDeclaration(codeText);

            LiteralToParameterExpansion exp = new LiteralToParameterExpansion();
            var perms = exp.FindCandidatesViaRefactoringPermutations(target);

            foreach (var perm in perms)
            {
                Debug.WriteLine(perm.PermutatedMethod.Print());
            }

            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i) { foo(i, 7, 8, 8); }"));
            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i) { foo(7, i, 8, 8); }"));
            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i) { foo(7, 7, i, 8); }"));
            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i) { foo(7, 7, 8, i); }"));

            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i) { foo(i, i, 8, 8); }"));
            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i) { foo(7, 7, i, i); }"));

            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i, int i2) { foo(i, 7, i2, 8); }"));
            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i, int i2) { foo(i, 7, 8, i2); }"));
            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i, int i2) { foo(7, i, i2, 8); }"));
            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i, int i2) { foo(7, i, 8, i2); }"));

            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i, int i2) { foo(7, i, 8, i2); }"));
            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i, int i2) { foo(i, 7, 8, i2); }"));
            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i, int i2) { foo(7, i, i2, 8); }"));
            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i, int i2) { foo(i, 7, i2, 8); }"));

            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i, int i2) { foo(i, i, i2, i2); }"));

            // I think that's all of them.  2^n-1 where n=4 is 15.
        }
        public void AllPossiblePermutationsOfASingleLiteral()
        {
            const string codeText = @"void Target() { Console.WriteLine(7); Console.Write(7); }";
            var target = AstMatchHelper.ParseToMethodDeclaration(codeText);

            LiteralToParameterExpansion exp = new LiteralToParameterExpansion();
            var perms = exp.FindCandidatesViaRefactoringPermutations(target);

            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i) { Console.WriteLine(i); Console.Write(i); }"), "Expected a permutation where all possible literals were replaced with a single parameter.");
            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i) { Console.WriteLine(i); Console.Write(7); }"), "Expected a permutation where the first literal was replaced, but not the second.");
            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i) { Console.WriteLine(7); Console.Write(i); }"), "Expected a permutation where the second literal was replaced, but not the first.");

            // Print out the permutations, just for reference.
            for (int i = 0; i < perms.ToArray().Length; i++)
            {
                var perm = perms.ToArray()[i];
                TestLog.EmbedPlainText("perm" + i, perm.PermutatedMethod.Print());
            }
        }
        public void MultipleCopiesOfALiteral()
        {
            const string codeText = @"void Target() { Console.WriteLine(7); Console.Write(7); }";
            var target = AstMatchHelper.ParseToMethodDeclaration(codeText);

            LiteralToParameterExpansion exp = new LiteralToParameterExpansion();
            var perms = exp.FindCandidatesViaRefactoringPermutations(target);

            AssertExists(perms, p => p.PermutatedMethod.MatchesPrint(AstMatchHelper.ParseToMethodDeclaration(@"void Expected(int i) { Console.WriteLine(i); Console.Write(i); }")), "Expected a permutation where all possible literals were replaced with a single parameter.");
        }
        public void SingleStringLiteralInstance()
        {
            const string codeText = @"void Target() { Console.WriteLine(""7""); }";
            var target = AstMatchHelper.ParseToMethodDeclaration(codeText);

            LiteralToParameterExpansion exp = new LiteralToParameterExpansion();
            var perms = exp.FindCandidatesViaRefactoringPermutations(target);

            Assert.IsTrue(perms.Any(p => p.PermutatedMethod.MatchesPrint(AstMatchHelper.ParseToMethodDeclaration(@"void Expected(string i) { Console.WriteLine(i); }"))));
        }
        public void SingleLiteralCanBeMultipleParams()
        {
            const string codeText = @"void Target() { Console.WriteLine(7); Console.Write(7); }";
            var target = AstMatchHelper.ParseToMethodDeclaration(codeText);

            LiteralToParameterExpansion exp = new LiteralToParameterExpansion();
            var perms = exp.FindCandidatesViaRefactoringPermutations(target);

            AssertExists(perms, p => p.MatchesIgnoreVarNames(@"void Expected(int i, int i1) { Console.WriteLine(i); Console.Write(i1); }"), "Expected a permutation where each literal gets it's own parameter, regardless of redundancy.");
        }
        public void SingleInstanceOfDifferentLiterals()
        {
            const string codeText = @"void Target() { Console.WriteLine(7); Console.Write(8); }";
            var target = AstMatchHelper.ParseToMethodDeclaration(codeText);

            LiteralToParameterExpansion exp = new LiteralToParameterExpansion();
            var perms = exp.FindCandidatesViaRefactoringPermutations(target);

            AssertExists(perms, p => p.PermutatedMethod.MatchesPrint(AstMatchHelper.ParseToMethodDeclaration(@"void Expected(int i, int i1) { Console.WriteLine(i); Console.Write(i1); }")), "Expected each literal to get it's own parameter, since they were not the same literal.");
        }
        public void PrimitiveExpressionForNullBug()
        {
            const string codeText = @"public void Foo()
                                {
                                    if (member != null)
                                    {

                                    }
                                }";
            var exp = new LiteralToParameterExpansion();
            var md = AstMatchHelper.ParseToMethodDeclaration(codeText);
            exp.FindCandidatesViaRefactoringPermutations(md).ToList();
        }