//biadsy
        private static HashSet <DVariable> GetVars(Microsoft.Dafny.Expression exp, HashSet <DVariable> declaredVars)
        {
            DVariableComparer   comparer = new DVariableComparer();
            HashSet <DVariable> vars     = new HashSet <DVariable>(comparer);

            if (exp is SeqSelectExpr)
            {
                var expr = exp as SeqSelectExpr;
                vars.UnionWith(GetVars(expr.Seq, declaredVars));
                vars.UnionWith(GetVars(expr.E0, declaredVars));
                vars.UnionWith(GetVars(expr.E1, declaredVars));
            }
            else if (exp is NameSegment)
            {
                var       expr = exp as NameSegment;
                DVariable var  = new DVariable(expr.Name, expr.Type);
                if (!declaredVars.Contains(var))
                {
                    vars.Add(var);
                }
            }
            else if (exp is ApplySuffix)
            {
                var expr = exp as ApplySuffix;
                foreach (var arg in expr.Args)
                {
                    vars.UnionWith(GetVars(arg, declaredVars));
                }
            }
            else if (exp is BinaryExpr)
            {
                var expr = exp as BinaryExpr;
                vars.UnionWith(GetVars(expr.E0, declaredVars));
                vars.UnionWith(GetVars(expr.E1, declaredVars));
            }
            else if (exp is UnaryOpExpr)
            {
                var expr = exp as UnaryOpExpr;
                vars.UnionWith(GetVars(expr.E, declaredVars));
            }
            else if (exp is ParensExpression)
            {
                var expr = exp as ParensExpression;
                vars.UnionWith(GetVars(expr.E, declaredVars));
            }
            else if (exp is ChainingExpression)
            {
                var expr = exp as ChainingExpression;
                vars.UnionWith(GetVars(expr.E, declaredVars));
            }
            else if (exp is SeqDisplayExpr)
            {
                var expr = exp as SeqDisplayExpr;
                foreach (var arg in expr.Elements)
                {
                    vars.UnionWith(GetVars(arg, declaredVars));
                }
            }
            else if (exp is Microsoft.Dafny.ForallExpr)
            {
                var expr       = exp as Microsoft.Dafny.ForallExpr;
                var newDecVars = new HashSet <DVariable>(declaredVars, comparer);
                if (expr.BoundVars != null)
                {
                    foreach (var bvar in expr.BoundVars)
                    {
                        DVariable dvar = new DVariable(bvar.DisplayName, bvar.Type);
                        newDecVars.Add(dvar);
                    }
                }
                vars.UnionWith(GetVars(expr.Term, newDecVars));
            }
            return(vars);
        }
        private void button_Click(object sender, RoutedEventArgs e)
        {
            this.Hide();
            DVariableComparer comparer = new DVariableComparer();
            List <Statement>  afterSelected;
            List <Statement>  selectedStatements = (List <Statement>)HelpFunctions.GetSelectedStatements();

            if (selectedStatements.Count == 0)
            {
                return;
            }

            //start and end of all relevant stmts and not only the selected ones.
            var start = selectedStatements[0].Tok.pos;

            if (selectedStatements[0] is UpdateStmt)
            {
                if (((UpdateStmt)selectedStatements[0]).Lhss.Count > 0)
                {
                    start = ((UpdateStmt)selectedStatements[0]).Lhss[0].tok.pos;
                }
                else if (((UpdateStmt)selectedStatements[0]).Rhss.Count > 0)
                {
                    if (((UpdateStmt)selectedStatements[0]).Rhss[0] is ExprRhs)
                    {
                        if (((ExprRhs)((UpdateStmt)selectedStatements[0]).Rhss[0]).Expr is ApplySuffix)
                        {
                            start -= ((NameSegment)((ApplySuffix)((ExprRhs)((UpdateStmt)selectedStatements[0]).Rhss[0]).Expr).Lhs).Name.Length;
                        }
                    }
                }
            }
            var end = selectedStatements[selectedStatements.Count - 1].EndTok.pos;

            HelpFunctions.GetSelectedStatements(out afterSelected).ToList();
            List <DVariable> tempIns       = new List <DVariable>();
            List <DVariable> tempOuts      = new List <DVariable>();
            List <DVariable> tempToDeclare = new List <DVariable>();

            HelpFunctions.GetVariables(selectedStatements, afterSelected, out tempIns, out tempOuts, out tempToDeclare);
            tempOuts = tempOuts.Union(tempToDeclare).ToList();
            List <DVariable>            intersect = tempIns.Intersect(tempOuts, comparer).ToList <DVariable>();
            Dictionary <string, string> renameDic = new Dictionary <string, string>();

            foreach (var x in intersect)
            {
                renameDic.Add(x.name, x.name + HelpFunctions.getNextIndex(x.name, tempIns, tempOuts, tempToDeclare));
            }
            List <Formal> ins  = new List <Formal>();
            List <Formal> outs = new List <Formal>();

            foreach (var x in tempIns)
            {
                DVariable temp = new DVariable(x.name, x.type);
                if (renameDic.ContainsKey(temp.name))
                {
                    temp.name = renameDic[temp.name];
                }
                ins.Add(temp.ToFormal());
            }

            foreach (var x in tempOuts)
            {
                outs.Add(x.ToFormal());
            }


            var requires = HelpFunctions.getPreAsserts(selectedStatements);
            var ensures  = HelpFunctions.getPostAsserts(selectedStatements);

            selectedStatements = HelpFunctions.removeReqAndEnsFromStmts(selectedStatements);
            selectedStatements = HelpFunctions.removeVarDeclFromStmts(selectedStatements);
            var method = HelpFunctions.GetCurrentMethod();
            List <MaybeFreeExpression> req = new List <MaybeFreeExpression>();

            foreach (var x in requires)
            {
                //HelpFunctions.renameB(x.Expr, renameDic);
                req.Add(new MaybeFreeExpression(HelpFunctions.renameB(x.Expr, renameDic)));
            }
            List <MaybeFreeExpression> ens = new List <MaybeFreeExpression>();

            foreach (var x in ensures)
            {
                ens.Add(new MaybeFreeExpression(x.Expr));
            }
            var newMethod = new Method(null, this.textBox.Text, false, false, new List <TypeParameter>(), ins, outs, req, new Specification <FrameExpression>(null, null), ens, new Specification <Microsoft.Dafny.Expression>(null, null), null, null, null);
            List <Microsoft.Dafny.Expression> Lhs = new List <Microsoft.Dafny.Expression>();
            List <AssignmentRhs> Rhs = new List <AssignmentRhs>();

            foreach (var x in intersect)
            {
                Lhs.Add(new NameSegment(null, x.name, new List <Type>()));
                Rhs.Add(new ExprRhs(new NameSegment(null, renameDic[x.name], new List <Type>())));
            }
            if (Lhs.Count > 0)
            {
                UpdateStmt correctingNames = new UpdateStmt(null, null, Lhs, Rhs);
                selectedStatements.Insert(0, correctingNames);
            }
            newMethod.Body = new BlockStmt(null, null, selectedStatements);
            // HelpFunctions.renameBody(newMethod.Body, new Dictionary<string, string>());///debug purposes only!!!!
            string signature = "aklt 5ra";
            string body      = "ya m3lm";

            try
            {
                signature = Printer.MethodSignatureToString(newMethod);
                body      = Printer.StatementToString(newMethod.Body);
            }
            catch (System.Exception ee)
            {
            }
            // Place the new method implementation in the code.
            int       position = HelpFunctions.GetCurrentMethod().BodyEndTok.pos + 1;
            ITextEdit edit     = HelpFunctions.GetWpfView().TextBuffer.CreateEdit();

            edit.Insert(position, "\r\n\r\n" + signature + "\r\n" + body);

            string methodcall = HelpFunctions.generateMethodCall(newMethod, tempIns, tempOuts);

            //DTE dte = (DTE)ExtractMethodPackage.GetGlobalService(typeof(DTE));
            //var selection = (EnvDTE.TextSelection)dte.ActiveDocument.Selection;

            edit.Delete(start, end - start + 1);
            edit.Insert(start, HelpFunctions.toDeclareString(tempToDeclare) + methodcall);
            edit.Apply();
            //selection.Text = methodcall;
        }
        //biadsy
        private static HashSet <DVariable> GetVars(Statement stmt, HashSet <DVariable> declaredVars, bool containNonModified)
        {
            DVariableComparer   comparer = new DVariableComparer();
            HashSet <DVariable> usedVars = new HashSet <DVariable>(comparer);

            if (stmt is UpdateStmt)
            {
                var ustmt = (UpdateStmt)stmt;
                foreach (var ls in ustmt.Lhss)
                {
                    usedVars.UnionWith(GetVars(ls, declaredVars));
                }
                if (containNonModified)
                {
                    foreach (var rs in ustmt.Rhss)
                    {
                        var exp = rs as ExprRhs;
                        usedVars.UnionWith(GetVars(exp.Expr, declaredVars));
                    }
                }
            }
            else if (stmt is AssertStmt && containNonModified)
            {
                var asrt = stmt as AssertStmt;
                usedVars.UnionWith(GetVars(asrt.Expr, declaredVars));
                usedVars.UnionWith(GetVars(asrt.Proof, declaredVars, containNonModified));
            }
            else if (stmt is WhileStmt)
            {
                var wstmt = stmt as WhileStmt;
                usedVars.UnionWith(GetVars(wstmt.Body, declaredVars, containNonModified));
                foreach (var exp in wstmt.Decreases.Expressions)
                {
                    usedVars.UnionWith(GetVars(exp, declaredVars));
                }
                usedVars.UnionWith(GetVars(wstmt.Guard, declaredVars));
                foreach (var exp in wstmt.Invariants)
                {
                    usedVars.UnionWith(GetVars(exp.E, declaredVars));
                }
            }
            else if (stmt is BlockStmt)
            {
                var stmts = stmt as BlockStmt;
                foreach (var bodyStmt in stmts.Body)
                {
                    usedVars.UnionWith(GetVars(bodyStmt, declaredVars, containNonModified));
                }
            }
            else if (stmt is CalcStmt)
            {
                var calcstmt = stmt as CalcStmt;
                foreach (var x in calcstmt.Lines)
                {
                    usedVars.UnionWith(GetVars(x, declaredVars));
                }
                foreach (var x in calcstmt.Hints)
                {
                    usedVars.UnionWith(GetVars(x, declaredVars, containNonModified));
                }
                foreach (var x in calcstmt.Steps)
                {
                    usedVars.UnionWith(GetVars(x, declaredVars));
                }
            }
            else if (stmt is VarDeclStmt)
            {
                var decl = stmt as VarDeclStmt;
                usedVars.UnionWith(GetVars(decl.Update, declaredVars, containNonModified));
                if (decl.Locals != null)
                {
                    foreach (var v in decl.Locals)
                    {
                        DVariable dvar = new DVariable(v.DisplayName, v.Type);
                        declaredVars.Add(dvar);
                    }
                }
            }
            else if (stmt is IfStmt)
            {
                var ifstmt = stmt as IfStmt;
                usedVars.UnionWith(GetVars(ifstmt.Guard, declaredVars));
                usedVars.UnionWith(GetVars(ifstmt.Thn, declaredVars, containNonModified));
                usedVars.UnionWith(GetVars(ifstmt.Els, declaredVars, containNonModified));
            }
            else if (stmt is PrintStmt)
            {
                var pstmt = stmt as PrintStmt;
                foreach (var arg in pstmt.Args)
                {
                    usedVars.UnionWith(GetVars(arg, declaredVars));
                }
            }

            return(usedVars);
        }