private static void InlineBlock(SequenceStatement seq, int index)
        {
            Statement first = seq.GetStats()[index];
            Statement pre   = seq.GetStats()[index - 1];

            pre.RemoveSuccessor(pre.GetAllSuccessorEdges()[0]);
            // single regular edge
            StatEdge  edge   = first.GetPredecessorEdges(StatEdge.Type_Break)[0];
            Statement source = edge.GetSource();
            Statement parent = source.GetParent();

            source.RemoveSuccessor(edge);
            List <Statement> lst = new List <Statement>();

            for (int i = seq.GetStats().Count - 1; i >= index; i--)
            {
                lst.Add(0, seq.GetStats().RemoveAtReturningValue(i));
            }
            if (parent.type == Statement.Type_If && ((IfStatement)parent).iftype == IfStatement
                .Iftype_If && source == parent.GetFirst())
            {
                IfStatement       ifparent = (IfStatement)parent;
                SequenceStatement block    = new SequenceStatement(lst);
                block.SetAllParent();
                StatEdge newedge = new StatEdge(StatEdge.Type_Regular, source, block);
                source.AddSuccessor(newedge);
                ifparent.SetIfEdge(newedge);
                ifparent.SetIfstat(block);
                ifparent.GetStats().AddWithKey(block, block.id);
                block.SetParent(ifparent);
            }
            else
            {
                lst.Add(0, source);
                SequenceStatement block = new SequenceStatement(lst);
                block.SetAllParent();
                parent.ReplaceStatement(source, block);
                // LabelHelper.lowContinueLabels not applicable because of forward continue edges
                // LabelHelper.lowContinueLabels(block, new HashSet<StatEdge>());
                // do it by hand
                foreach (StatEdge prededge in block.GetPredecessorEdges(StatEdge.Type_Continue))
                {
                    block.RemovePredecessor(prededge);
                    prededge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, prededge, source
                                                        );
                    source.AddPredecessor(prededge);
                    source.AddLabeledEdge(prededge);
                }
                if (parent.type == Statement.Type_Switch)
                {
                    ((SwitchStatement)parent).SortEdgesAndNodes();
                }
                source.AddSuccessor(new StatEdge(StatEdge.Type_Regular, source, first));
            }
        }
Exemplo n.º 2
0
 private static Statement CopyStatement(Statement from, Statement to, Dictionary <Statement
                                                                                  , Statement> mapAltToCopies)
 {
     if (to == null)
     {
         // first outer invocation
         to = from.GetSimpleCopy();
         Sharpen.Collections.Put(mapAltToCopies, from, to);
     }
     // copy statements
     foreach (Statement st in from.GetStats())
     {
         Statement stcopy = st.GetSimpleCopy();
         to.GetStats().AddWithKey(stcopy, stcopy.id);
         Sharpen.Collections.Put(mapAltToCopies, st, stcopy);
     }
     // copy edges
     for (int i = 0; i < from.GetStats().Count; i++)
     {
         Statement stold = from.GetStats()[i];
         Statement stnew = to.GetStats()[i];
         foreach (StatEdge edgeold in stold.GetSuccessorEdges(Statement.Statedge_Direct_All
                                                              ))
         {
             // type cannot be TYPE_EXCEPTION (checked in isIrreducibleTriangle)
             StatEdge edgenew = new StatEdge(edgeold.GetType(), stnew, mapAltToCopies.ContainsKey
                                                 (edgeold.GetDestination()) ? mapAltToCopies.GetOrNull(edgeold.GetDestination()) :
                                             edgeold.GetDestination(), mapAltToCopies.ContainsKey(edgeold.closure) ? mapAltToCopies
                                             .GetOrNull(edgeold.closure) : edgeold.closure);
             stnew.AddSuccessor(edgenew);
         }
     }
     // recurse statements
     for (int i = 0; i < from.GetStats().Count; i++)
     {
         Statement stold = from.GetStats()[i];
         Statement stnew = to.GetStats()[i];
         CopyStatement(stold, stnew, mapAltToCopies);
     }
     return(to);
 }
Exemplo n.º 3
0
        public static bool SplitIrreducibleNode(Statement statement)
        {
            Statement splitnode = GetCandidateForSplitting(statement);

            if (splitnode == null)
            {
                return(false);
            }
            StatEdge enteredge = splitnode.GetPredecessorEdges(StatEdge.Type_Regular).GetEnumerator
                                     ().Current;
            // copy the smallest statement
            Statement splitcopy = CopyStatement(splitnode, null, new Dictionary <Statement, Statement
                                                                                 >());

            InitCopiedStatement(splitcopy);
            // insert the copy
            splitcopy.SetParent(statement);
            statement.GetStats().AddWithKey(splitcopy, splitcopy.id);
            // switch input edges
            foreach (StatEdge prededge in splitnode.GetPredecessorEdges(Statement.Statedge_Direct_All
                                                                        ))
            {
                if (prededge.GetSource() == enteredge.GetSource() || prededge.closure == enteredge
                    .GetSource())
                {
                    splitnode.RemovePredecessor(prededge);
                    prededge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, prededge, splitcopy
                                                        );
                    splitcopy.AddPredecessor(prededge);
                }
            }
            // connect successors
            foreach (StatEdge succ in splitnode.GetSuccessorEdges(Statement.Statedge_Direct_All
                                                                  ))
            {
                splitcopy.AddSuccessor(new StatEdge(succ.GetType(), splitcopy, succ.GetDestination
                                                        (), succ.closure));
            }
            return(true);
        }
Exemplo n.º 4
0
 private static void BuildSynchronized(Statement stat)
 {
     foreach (Statement st in stat.GetStats())
     {
         BuildSynchronized(st);
     }
     if (stat.type == Statement.Type_Sequence)
     {
         while (true)
         {
             bool             found = false;
             List <Statement> lst   = stat.GetStats();
             for (int i = 0; i < lst.Count - 1; i++)
             {
                 Statement current = lst[i];
                 // basic block
                 if (current.IsMonitorEnter())
                 {
                     Statement next       = lst[i + 1];
                     Statement nextDirect = next;
                     while (next.type == Statement.Type_Sequence)
                     {
                         next = next.GetFirst();
                     }
                     if (next.type == Statement.Type_Catchall)
                     {
                         CatchAllStatement ca = (CatchAllStatement)next;
                         if (ca.GetFirst().IsContainsMonitorExit() && ca.GetHandler().IsContainsMonitorExit
                                 ())
                         {
                             // remove the head block from sequence
                             current.RemoveSuccessor(current.GetSuccessorEdges(Statement.Statedge_Direct_All)[
                                                         0]);
                             foreach (StatEdge edge in current.GetPredecessorEdges(Statement.Statedge_Direct_All
                                                                                   ))
                             {
                                 current.RemovePredecessor(edge);
                                 edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, nextDirect);
                                 nextDirect.AddPredecessor(edge);
                             }
                             stat.GetStats().RemoveWithKey(current.id);
                             stat.SetFirst(stat.GetStats()[0]);
                             // new statement
                             SynchronizedStatement sync = new SynchronizedStatement(current, ca.GetFirst(), ca
                                                                                    .GetHandler());
                             sync.SetAllParent();
                             foreach (StatEdge edge in new HashSet <StatEdge>(ca.GetLabelEdges()))
                             {
                                 sync.AddLabeledEdge(edge);
                             }
                             current.AddSuccessor(new StatEdge(StatEdge.Type_Regular, current, ca.GetFirst()));
                             ca.GetParent().ReplaceStatement(ca, sync);
                             found = true;
                             break;
                         }
                     }
                 }
             }
             if (!found)
             {
                 break;
             }
         }
     }
 }
Exemplo n.º 5
0
        private static RootStatement GraphToStatement(ControlFlowGraph graph)
        {
            VBStyleCollection <Statement, int>  stats  = new VBStyleCollection <Statement, int>();
            VBStyleCollection <BasicBlock, int> blocks = graph.GetBlocks();

            foreach (BasicBlock block in blocks)
            {
                stats.AddWithKey(new BasicBlockStatement(block), block.id);
            }
            BasicBlock firstblock = graph.GetFirst();
            // head statement
            Statement firstst = stats.GetWithKey(firstblock.id);
            // dummy exit statement
            DummyExitStatement dummyexit = new DummyExitStatement();
            Statement          general;

            if (stats.Count > 1 || firstblock.IsSuccessor(firstblock))
            {
                // multiple basic blocks or an infinite loop of one block
                general = new GeneralStatement(firstst, stats, null);
            }
            else
            {
                // one straightforward basic block
                RootStatement root = new RootStatement(firstst, dummyexit);
                firstst.AddSuccessor(new StatEdge(StatEdge.Type_Break, firstst, dummyexit, root));
                return(root);
            }
            foreach (BasicBlock block in blocks)
            {
                Statement stat = stats.GetWithKey(block.id);
                foreach (BasicBlock succ in block.GetSuccs())
                {
                    Statement stsucc = stats.GetWithKey(succ.id);
                    int       type;
                    if (stsucc == firstst)
                    {
                        type = StatEdge.Type_Continue;
                    }
                    else if (graph.GetFinallyExits().Contains(block))
                    {
                        type   = StatEdge.Type_Finallyexit;
                        stsucc = dummyexit;
                    }
                    else if (succ.id == graph.GetLast().id)
                    {
                        type   = StatEdge.Type_Break;
                        stsucc = dummyexit;
                    }
                    else
                    {
                        type = StatEdge.Type_Regular;
                    }
                    stat.AddSuccessor(new StatEdge(type, stat, (type == StatEdge.Type_Continue) ? general
                                                 : stsucc, (type == StatEdge.Type_Regular) ? null : general));
                }
                // exceptions edges
                foreach (BasicBlock succex in block.GetSuccExceptions())
                {
                    Statement         stsuccex = stats.GetWithKey(succex.id);
                    ExceptionRangeCFG range    = graph.GetExceptionRange(succex, block);
                    if (!range.IsCircular())
                    {
                        stat.AddSuccessor(new StatEdge(stat, stsuccex, range.GetExceptionTypes()));
                    }
                }
            }
            general.BuildContinueSet();
            general.BuildMonitorFlags();
            return(new RootStatement(general, dummyexit));
        }
Exemplo n.º 6
0
        private static void ProcessEdgesWithNext(Statement stat, Dictionary <Statement, List <StatEdge> > mapEdges, Statement next)
        {
            StatEdge        statedge = null;
            List <StatEdge> lstSuccs = stat.GetAllSuccessorEdges();

            if (!(lstSuccs.Count == 0))
            {
                statedge = lstSuccs[0];
                if (statedge.GetDestination() == next)
                {
                    statedge.@explicit = false;
                    statedge           = null;
                }
                else
                {
                    next = statedge.GetDestination();
                }
            }
            // no next for a do statement
            if (stat.type == Statement.Type_Do && ((DoStatement)stat).GetLooptype() == DoStatement
                .Loop_Do)
            {
                next = null;
            }
            if (next == null)
            {
                if (mapEdges.Count == 1)
                {
                    List <StatEdge> lstEdges = new Sharpen.EnumeratorAdapter <List <StatEdge> >(mapEdges.Values.GetEnumerator()).Next();
                    if (lstEdges.Count > 1 && new Sharpen.EnumeratorAdapter <Statement>(mapEdges.Keys.GetEnumerator()).Next().type != Statement
                        .Type_Dummyexit)
                    {
                        StatEdge  edge_example = lstEdges[0];
                        Statement closure      = stat.GetParent();
                        if (!closure.ContainsStatementStrict(edge_example.closure))
                        {
                            closure = edge_example.closure;
                        }
                        StatEdge newedge = new StatEdge(edge_example.GetType(), stat, edge_example.GetDestination
                                                            (), closure);
                        stat.AddSuccessor(newedge);
                        foreach (StatEdge edge in lstEdges)
                        {
                            edge.@explicit = false;
                        }
                        Sharpen.Collections.Put(mapEdges, newedge.GetDestination(), new List <StatEdge>(System.Linq.Enumerable.ToList(new [] {
                            newedge
                        })));
                    }
                }
            }
            else
            {
                bool implfound = false;
                foreach (KeyValuePair <Statement, List <StatEdge> > entr in mapEdges)
                {
                    if (entr.Key == next)
                    {
                        foreach (StatEdge edge in entr.Value)
                        {
                            edge.@explicit = false;
                        }
                        implfound = true;
                        break;
                    }
                }
                if ((stat.GetAllSuccessorEdges().Count == 0) && !implfound)
                {
                    List <StatEdge> lstEdges = null;
                    foreach (KeyValuePair <Statement, List <StatEdge> > entr in mapEdges)
                    {
                        if (entr.Key.type != Statement.Type_Dummyexit && (lstEdges == null || entr.Value.
                                                                          Count > lstEdges.Count))
                        {
                            lstEdges = entr.Value;
                        }
                    }
                    if (lstEdges != null && lstEdges.Count > 1)
                    {
                        StatEdge  edge_example = lstEdges[0];
                        Statement closure      = stat.GetParent();
                        if (!closure.ContainsStatementStrict(edge_example.closure))
                        {
                            closure = edge_example.closure;
                        }
                        StatEdge newedge = new StatEdge(edge_example.GetType(), stat, edge_example.GetDestination
                                                            (), closure);
                        stat.AddSuccessor(newedge);
                        foreach (StatEdge edge in lstEdges)
                        {
                            edge.@explicit = false;
                        }
                    }
                }
                mapEdges.Clear();
            }
            if (statedge != null)
            {
                Sharpen.Collections.Put(mapEdges, statedge.GetDestination(), new List <StatEdge>(System.Linq.Enumerable.ToList(new [] {
                    statedge
                })));
            }
        }
Exemplo n.º 7
0
 private static void CondenseSequencesRec(Statement stat)
 {
     if (stat.type == Statement.Type_Sequence)
     {
         List <Statement> lst      = new List <Statement>(stat.GetStats());
         bool             unfolded = false;
         // unfold blocks
         for (int i = 0; i < lst.Count; i++)
         {
             Statement st = lst[i];
             if (st.type == Statement.Type_Sequence)
             {
                 RemoveEmptyStatements((SequenceStatement)st);
                 if (i == lst.Count - 1 || IsSequenceDisbandable(st, lst[i + 1]))
                 {
                     // move predecessors
                     Statement first = st.GetFirst();
                     foreach (StatEdge edge in st.GetAllPredecessorEdges())
                     {
                         st.RemovePredecessor(edge);
                         edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, first);
                         first.AddPredecessor(edge);
                     }
                     // move successors
                     Statement last = st.GetStats().GetLast();
                     if ((last.GetAllSuccessorEdges().Count == 0) && i < lst.Count - 1)
                     {
                         last.AddSuccessor(new StatEdge(StatEdge.Type_Regular, last, lst[i + 1]));
                     }
                     else
                     {
                         foreach (StatEdge edge in last.GetAllSuccessorEdges())
                         {
                             if (i == lst.Count - 1)
                             {
                                 if (edge.closure == st)
                                 {
                                     stat.AddLabeledEdge(edge);
                                 }
                             }
                             else
                             {
                                 edge.GetSource().ChangeEdgeType(Statement.Direction_Forward, edge, StatEdge.Type_Regular
                                                                 );
                                 edge.closure.GetLabelEdges().Remove(edge);
                                 edge.closure = null;
                             }
                         }
                     }
                     foreach (StatEdge edge in st.GetAllSuccessorEdges())
                     {
                         st.RemoveSuccessor(edge);
                     }
                     foreach (StatEdge edge in new HashSet <StatEdge>(st.GetLabelEdges()))
                     {
                         if (edge.GetSource() != last)
                         {
                             last.AddLabeledEdge(edge);
                         }
                     }
                     lst.RemoveAtReturningValue(i);
                     lst.InsertRange(i, st.GetStats());
                     i--;
                     unfolded = true;
                 }
             }
         }
         if (unfolded)
         {
             SequenceStatement sequence = new SequenceStatement(lst);
             sequence.SetAllParent();
             stat.GetParent().ReplaceStatement(stat, sequence);
             stat = sequence;
         }
     }
     // sequence consisting of one statement -> disband
     if (stat.type == Statement.Type_Sequence)
     {
         RemoveEmptyStatements((SequenceStatement)stat);
         if (stat.GetStats().Count == 1)
         {
             Statement st = stat.GetFirst();
             bool      ok = (st.GetAllSuccessorEdges().Count == 0);
             if (!ok)
             {
                 StatEdge edge = st.GetAllSuccessorEdges()[0];
                 ok = (stat.GetAllSuccessorEdges().Count == 0);
                 if (!ok)
                 {
                     StatEdge statedge = stat.GetAllSuccessorEdges()[0];
                     ok = (edge.GetDestination() == statedge.GetDestination());
                     if (ok)
                     {
                         st.RemoveSuccessor(edge);
                     }
                 }
             }
             if (ok)
             {
                 stat.GetParent().ReplaceStatement(stat, st);
                 stat = st;
             }
         }
     }
     // replace flat statements with synthetic basic blocks
     while (true)
     {
         foreach (Statement st in stat.GetStats())
         {
             if (((st.GetStats().Count == 0) || st.GetExprents() != null) && st.type != Statement
                 .Type_Basicblock)
             {
                 DestroyAndFlattenStatement(st);
                 goto outer_continue;
             }
         }
         break;
         outer_continue :;
     }
     outer_break :;
     // recursion
     for (int i = 0; i < stat.GetStats().Count; i++)
     {
         CondenseSequencesRec(stat.GetStats()[i]);
     }
 }
Exemplo n.º 8
0
 private static bool CollapseElse(IfHelper.IfNode rtnode)
 {
     if (rtnode.edgetypes[1] == 0)
     {
         IfHelper.IfNode elsebranch = rtnode.succs[1];
         if (elsebranch.succs.Count == 2)
         {
             // else-if or else-else branch
             int path = elsebranch.succs[1].value == rtnode.succs[0].value ? 2 : (elsebranch.succs
                                                                                  [0].value == rtnode.succs[0].value ? 1 : 0);
             if (path > 0)
             {
                 IfStatement firstif  = (IfStatement)rtnode.value;
                 IfStatement secondif = (IfStatement)elsebranch.value;
                 Statement   parent   = firstif.GetParent();
                 if ((secondif.GetFirst().GetExprents().Count == 0))
                 {
                     firstif.GetFirst().RemoveSuccessor(firstif.GetIfEdge());
                     // remove first if
                     firstif.RemoveAllSuccessors(secondif);
                     foreach (StatEdge edge in firstif.GetAllPredecessorEdges())
                     {
                         if (!firstif.ContainsStatementStrict(edge.GetSource()))
                         {
                             firstif.RemovePredecessor(edge);
                             edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, secondif);
                             secondif.AddPredecessor(edge);
                         }
                     }
                     parent.GetStats().RemoveWithKey(firstif.id);
                     if (parent.GetFirst() == firstif)
                     {
                         parent.SetFirst(secondif);
                     }
                     // merge if conditions
                     IfExprent      statexpr    = secondif.GetHeadexprent();
                     List <Exprent> lstOperands = new List <Exprent>();
                     lstOperands.Add(firstif.GetHeadexprent().GetCondition());
                     if (path == 2)
                     {
                         lstOperands[0] = new FunctionExprent(FunctionExprent.Function_Bool_Not, lstOperands
                                                              [0], null);
                     }
                     lstOperands.Add(statexpr.GetCondition());
                     statexpr.SetCondition(new FunctionExprent(path == 1 ? FunctionExprent.Function_Cor
                                                          : FunctionExprent.Function_Cadd, lstOperands, null));
                     if ((secondif.GetFirst().GetExprents().Count == 0) && !(firstif.GetFirst().GetExprents
                                                                                 ().Count == 0))
                     {
                         secondif.ReplaceStatement(secondif.GetFirst(), firstif.GetFirst());
                     }
                     return(true);
                 }
             }
         }
         else if (elsebranch.succs.Count == 1)
         {
             if (elsebranch.succs[0].value == rtnode.succs[0].value)
             {
                 IfStatement firstif = (IfStatement)rtnode.value;
                 Statement   second  = elsebranch.value;
                 firstif.RemoveAllSuccessors(second);
                 foreach (StatEdge edge in second.GetAllSuccessorEdges())
                 {
                     second.RemoveSuccessor(edge);
                     edge.SetSource(firstif);
                     firstif.AddSuccessor(edge);
                 }
                 StatEdge ifedge = firstif.GetIfEdge();
                 firstif.GetFirst().RemoveSuccessor(ifedge);
                 second.AddSuccessor(new StatEdge(ifedge.GetType(), second, ifedge.GetDestination(
                                                      ), ifedge.closure));
                 StatEdge newifedge = new StatEdge(StatEdge.Type_Regular, firstif.GetFirst(), second
                                                   );
                 firstif.GetFirst().AddSuccessor(newifedge);
                 firstif.SetIfstat(second);
                 firstif.GetStats().AddWithKey(second, second.id);
                 second.SetParent(firstif);
                 firstif.GetParent().GetStats().RemoveWithKey(second.id);
                 // negate the if condition
                 IfExprent statexpr = firstif.GetHeadexprent();
                 statexpr.SetCondition(new FunctionExprent(FunctionExprent.Function_Bool_Not, statexpr
                                                           .GetCondition(), null));
                 return(true);
             }
         }
     }
     return(false);
 }
Exemplo n.º 9
0
        private static int IntegrateExits(Statement stat)
        {
            int       ret = 0;
            Statement dest;

            if (stat.GetExprents() == null)
            {
                while (true)
                {
                    int changed = 0;
                    foreach (Statement st in stat.GetStats())
                    {
                        changed = IntegrateExits(st);
                        if (changed > 0)
                        {
                            ret = 1;
                            break;
                        }
                    }
                    if (changed == 0)
                    {
                        break;
                    }
                }
                if (stat.type == Statement.Type_If)
                {
                    IfStatement ifst = (IfStatement)stat;
                    if (ifst.GetIfstat() == null)
                    {
                        StatEdge ifedge = ifst.GetIfEdge();
                        dest = IsExitEdge(ifedge);
                        if (dest != null)
                        {
                            BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext
                                                                                               .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter
                                                                                                                                             )));
                            bstat.SetExprents(DecHelper.CopyExprentList(dest.GetExprents()));
                            ifst.GetFirst().RemoveSuccessor(ifedge);
                            StatEdge newedge = new StatEdge(StatEdge.Type_Regular, ifst.GetFirst(), bstat);
                            ifst.GetFirst().AddSuccessor(newedge);
                            ifst.SetIfEdge(newedge);
                            ifst.SetIfstat(bstat);
                            ifst.GetStats().AddWithKey(bstat, bstat.id);
                            bstat.SetParent(ifst);
                            StatEdge oldexitedge = dest.GetAllSuccessorEdges()[0];
                            StatEdge newexitedge = new StatEdge(StatEdge.Type_Break, bstat, oldexitedge.GetDestination
                                                                    ());
                            bstat.AddSuccessor(newexitedge);
                            oldexitedge.closure.AddLabeledEdge(newexitedge);
                            ret = 1;
                        }
                    }
                }
            }
            if (stat.GetAllSuccessorEdges().Count == 1 && stat.GetAllSuccessorEdges()[0].GetType
                    () == StatEdge.Type_Break && (stat.GetLabelEdges().Count == 0))
            {
                Statement parent = stat.GetParent();
                if (stat != parent.GetFirst() || (parent.type != Statement.Type_If && parent.type
                                                  != Statement.Type_Switch))
                {
                    StatEdge destedge = stat.GetAllSuccessorEdges()[0];
                    dest = IsExitEdge(destedge);
                    if (dest != null)
                    {
                        stat.RemoveSuccessor(destedge);
                        BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext
                                                                                           .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter
                                                                                                                                         )));
                        bstat.SetExprents(DecHelper.CopyExprentList(dest.GetExprents()));
                        StatEdge oldexitedge = dest.GetAllSuccessorEdges()[0];
                        StatEdge newexitedge = new StatEdge(StatEdge.Type_Break, bstat, oldexitedge.GetDestination
                                                                ());
                        bstat.AddSuccessor(newexitedge);
                        oldexitedge.closure.AddLabeledEdge(newexitedge);
                        SequenceStatement block = new SequenceStatement(Sharpen.Arrays.AsList(stat, bstat
                                                                                              ));
                        block.SetAllParent();
                        parent.ReplaceStatement(stat, block);
                        // LabelHelper.lowContinueLabels not applicable because of forward continue edges
                        // LabelHelper.lowContinueLabels(block, new HashSet<StatEdge>());
                        // do it by hand
                        foreach (StatEdge prededge in block.GetPredecessorEdges(StatEdge.Type_Continue))
                        {
                            block.RemovePredecessor(prededge);
                            prededge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, prededge, stat);
                            stat.AddPredecessor(prededge);
                            stat.AddLabeledEdge(prededge);
                        }
                        stat.AddSuccessor(new StatEdge(StatEdge.Type_Regular, stat, bstat));
                        foreach (StatEdge edge in dest.GetAllPredecessorEdges())
                        {
                            if (!edge.@explicit && stat.ContainsStatementStrict(edge.GetSource()) && MergeHelper
                                .IsDirectPath(edge.GetSource().GetParent(), bstat))
                            {
                                dest.RemovePredecessor(edge);
                                edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, bstat);
                                bstat.AddPredecessor(edge);
                                if (!stat.ContainsStatementStrict(edge.closure))
                                {
                                    stat.AddLabeledEdge(edge);
                                }
                            }
                        }
                        ret = 2;
                    }
                }
            }
            return(ret);
        }