Program: 61532
Project: 61532
Buggy source:
protected List<GraphTargetItem> printGraph(Map<GraphPart,List<GraphTargetItem>> partCodes,Map<GraphPart,Integer> partCodePos,List<GraphPart> visited,BaseLocalData localData,TranslateStack stack,List<GraphPart> allParts,GraphPart parent,GraphPart part,List<GraphPart> stopPart,List<Loop> loops,List<GraphTargetItem> ret,int staticOperation,String path,int recursionLevel) throws InterruptedException {
  if (Thread.currentThread().isInterrupted()) {
    throw new InterruptedException();
  }
  if (stopPart == null) {
    stopPart=new ArrayList<>();
  }
  if (recursionLevel > allParts.size() + 1) {
    throw new TranslateException("String_Node_Str");
  }
  if (ret == null) {
    ret=new ArrayList<>();
  }
  boolean debugMode=false;
  if (debugMode) {
    System.err.println("String_Node_Str" + part + "String_Node_Str"+ part.nextParts.size());
  }
  if (part == null) {
    return ret;
  }
  part=checkPart(stack,localData,part,allParts);
  if (part == null) {
    return ret;
  }
  if (part.ignored) {
    return ret;
  }
  List<GraphPart> loopContinues=getLoopsContinues(loops);
  boolean isLoop=false;
  Loop currentLoop=null;
  for (  Loop el : loops) {
    if ((el.loopContinue == part) && (el.phase == 0)) {
      currentLoop=el;
      currentLoop.phase=1;
      isLoop=true;
      break;
    }
  }
  if (debugMode) {
    System.err.println("String_Node_Str" + loops.size());
  }
  for (int l=loops.size() - 1; l >= 0; l--) {
    Loop el=loops.get(l);
    if (el == currentLoop) {
      if (debugMode) {
        System.err.println("String_Node_Str" + el);
      }
      continue;
    }
    if (el.phase != 1) {
      if (debugMode) {
        System.err.println("String_Node_Str" + el);
      }
      continue;
    }
    if (el.loopBreak == part) {
      if (currentLoop != null) {
        currentLoop.phase=0;
      }
      if (debugMode) {
        System.err.println("String_Node_Str");
      }
      ret.add(new BreakItem(null,el.id));
      return ret;
    }
    if (el.loopPreContinue == part) {
      if (currentLoop != null) {
        currentLoop.phase=0;
      }
      if (debugMode) {
        System.err.println("String_Node_Str");
      }
      ret.add(new ContinueItem(null,el.id));
      return ret;
    }
    if (el.loopContinue == part) {
      if (currentLoop != null) {
        currentLoop.phase=0;
      }
      if (debugMode) {
        System.err.println("String_Node_Str");
      }
      ret.add(new ContinueItem(null,el.id));
      return ret;
    }
  }
  if (stopPart.contains(part)) {
    if (currentLoop != null) {
      currentLoop.phase=0;
    }
    if (debugMode) {
      System.err.println("String_Node_Str" + part);
    }
    return ret;
  }
  if ((part != null) && (code.size() <= part.start)) {
    ret.add(new ScriptEndItem());
    return ret;
  }
  if (visited.contains(part)) {
    String labelName="String_Node_Str" + part.start;
    List<GraphTargetItem> firstCode=partCodes.get(part);
    int firstCodePos=partCodePos.get(part);
    if (firstCodePos > firstCode.size()) {
      firstCodePos=firstCode.size();
    }
    if (firstCode.size() > firstCodePos && (firstCode.get(firstCodePos) instanceof LabelItem)) {
      labelName=((LabelItem)firstCode.get(firstCodePos)).labelName;
    }
 else {
      firstCode.add(firstCodePos,new LabelItem(null,labelName));
    }
    ret.add(new GotoItem(null,labelName));
    return ret;
  }
 else {
    visited.add(part);
    partCodes.put(part,ret);
    partCodePos.put(part,ret.size());
  }
  List<GraphTargetItem> currentRet=ret;
  UniversalLoopItem loopItem=null;
  TranslateStack sPreLoop=stack;
  if (isLoop) {
    stack=(TranslateStack)stack.clone();
    stack.clear();
    loopItem=new UniversalLoopItem(null,currentLoop);
    currentRet.add(loopItem);
    loopItem.commands=new ArrayList<>();
    currentRet=loopItem.commands;
  }
  boolean parseNext=true;
  List<GraphTargetItem> output=new ArrayList<>();
  List<GraphPart> parts=new ArrayList<>();
  if (part instanceof GraphPartMulti) {
    parts=((GraphPartMulti)part).parts;
  }
 else {
    parts.add(part);
  }
  for (  GraphPart p : parts) {
    int end=p.end;
    int start=p.start;
    output.addAll(code.translatePart(p,localData,stack,start,end,staticOperation,path));
    if ((end >= code.size() - 1) && p.nextParts.isEmpty()) {
      output.add(new ScriptEndItem());
    }
  }
  if (parseNext) {
    List<GraphTargetItem> retCheck=check(partCodes,partCodePos,code,localData,allParts,stack,parent,part,stopPart,loops,output,currentLoop,staticOperation,path);
    if (retCheck != null) {
      if (!retCheck.isEmpty()) {
        currentRet.addAll(retCheck);
      }
      parseNext=false;
    }
 else {
      currentRet.addAll(output);
    }
  }
  if (parseNext) {
    if (part.nextParts.size() > 2) {
      GraphPart next=getMostCommonPart(localData,part.nextParts,loops);
      List<GraphPart> vis=new ArrayList<>();
      GraphTargetItem switchedItem=stack.pop();
      makeAllCommands(currentRet,stack);
      List<GraphTargetItem> caseValues=new ArrayList<>();
      List<List<GraphTargetItem>> caseCommands=new ArrayList<>();
      List<GraphTargetItem> defaultCommands=new ArrayList<>();
      List<Integer> valueMappings=new ArrayList<>();
      Loop swLoop=new Loop(loops.size(),null,next);
      swLoop.phase=1;
      loops.add(swLoop);
      boolean first=false;
      int pos=0;
      Map<Integer,GraphTargetItem> caseExpressions=new HashMap<>();
      Map<Integer,GraphTargetItem> caseExpressionLeftSides=new HashMap<>();
      Map<Integer,GraphTargetItem> caseExpressionRightSides=new HashMap<>();
      GraphTargetItem it=switchedItem;
      int defaultBranch=0;
      boolean hasExpr=false;
      while (it instanceof TernarOpItem) {
        TernarOpItem to=(TernarOpItem)it;
        if (to.expression instanceof EqualsTypeItem) {
          if (to.onTrue instanceof IntegerValueTypeItem) {
            int cpos=((IntegerValueTypeItem)to.onTrue).intValue();
            caseExpressionLeftSides.put(cpos,((EqualsTypeItem)to.expression).getLeftSide());
            caseExpressionRightSides.put(cpos,((EqualsTypeItem)to.expression).getRightSide());
            it=to.onFalse;
          }
 else {
            break;
          }
        }
 else {
          break;
        }
      }
      if (it instanceof IntegerValueTypeItem) {
        defaultBranch=((IntegerValueTypeItem)it).intValue();
      }
      if (!caseExpressionRightSides.isEmpty()) {
        GraphTargetItem firstItem;
        firstItem=(GraphTargetItem)caseExpressionRightSides.values().toArray()[0];
        boolean sameRight=true;
        for (        GraphTargetItem cit : caseExpressionRightSides.values()) {
          if (!cit.equals(firstItem)) {
            sameRight=false;
            break;
          }
        }
        if (sameRight) {
          caseExpressions=caseExpressionLeftSides;
          switchedItem=firstItem;
          hasExpr=true;
        }
 else {
          firstItem=(GraphTargetItem)caseExpressionLeftSides.values().toArray()[0];
          boolean sameLeft=true;
          for (          GraphTargetItem cit : caseExpressionLeftSides.values()) {
            if (!cit.equals(firstItem)) {
              sameLeft=false;
              break;
            }
          }
          if (sameLeft) {
            caseExpressions=caseExpressionRightSides;
            switchedItem=firstItem;
            hasExpr=true;
          }
        }
      }
      first=true;
      pos=0;
      GraphPart defaultPart=hasExpr ? part.nextParts.get(1 + defaultBranch) : part.nextParts.get(0);
      for (      GraphPart p : part.nextParts) {
        if (p != defaultPart) {
          if (caseExpressions.containsKey(pos)) {
            caseValues.add(caseExpressions.get(pos));
          }
 else {
            caseValues.add(new IntegerValueItem(null,pos));
          }
          pos++;
        }
      }
      first=true;
      pos=0;
      List<GraphTargetItem> nextCommands=new ArrayList<>();
      for (      GraphPart p : part.nextParts) {
        if (p != defaultPart) {
          if (vis.contains(p)) {
            valueMappings.add(caseCommands.size() - 1);
            continue;
          }
          valueMappings.add(caseCommands.size());
        }
        List<GraphPart> stopPart2=new ArrayList<>();
        if (next != null) {
          stopPart2.add(next);
        }
 else         if (!stopPart.isEmpty()) {
          stopPart2.add(stopPart.get(stopPart.size() - 1));
        }
        for (        GraphPart p2 : part.nextParts) {
          if (p2 == p) {
            continue;
          }
          if (!stopPart2.contains(p2)) {
            stopPart2.add(p2);
          }
        }
        if (next != p) {
          if (p == defaultPart && !defaultCommands.isEmpty()) {
          }
 else {
            TranslateStack s2=(TranslateStack)stack.clone();
            s2.clear();
            nextCommands=printGraph(partCodes,partCodePos,visited,prepareBranchLocalData(localData),s2,allParts,part,p,stopPart2,loops,null,staticOperation,path,recursionLevel + 1);
            makeAllCommands(nextCommands,s2);
            if (p == defaultPart) {
              defaultCommands=nextCommands;
            }
 else {
              caseCommands.add(nextCommands);
            }
            vis.add(p);
          }
        }
 else {
          if (p == defaultPart) {
            defaultCommands=nextCommands;
          }
 else {
            caseCommands.add(nextCommands);
          }
        }
        first=false;
        pos++;
      }
      if (!defaultCommands.isEmpty() && (defaultCommands.get(defaultCommands.size() - 1) instanceof BreakItem)) {
        BreakItem bi=(BreakItem)defaultCommands.get(defaultCommands.size() - 1);
        if (bi.loopId == swLoop.id) {
          defaultCommands.remove(defaultCommands.size() - 1);
        }
      }
      SwitchItem sw=new SwitchItem(null,swLoop,switchedItem,caseValues,caseCommands,defaultCommands,valueMappings);
      currentRet.add(sw);
      swLoop.phase=2;
      if (next != null) {
        currentRet.addAll(printGraph(partCodes,partCodePos,visited,localData,stack,allParts,part,next,stopPart,loops,null,staticOperation,path,recursionLevel + 1));
      }
      pos++;
    }
    GraphPart nextOnePart=null;
    if (part.nextParts.size() == 2) {
      GraphTargetItem expr=stack.pop();
      if (nextOnePart == null) {
        List<GraphPart> nps;
        nps=part.nextParts;
        boolean isEmpty=nps.get(0) == nps.get(1);
        GraphPart next=getCommonPart(localData,nps,loops);
        TranslateStack trueStack=(TranslateStack)stack.clone();
        TranslateStack falseStack=(TranslateStack)stack.clone();
        trueStack.clear();
        falseStack.clear();
        if (isEmpty) {
          next=nps.get(0);
        }
        boolean hasOntrue=nps.get(1) != next;
        boolean hasOnFalse=nps.get(0) != next;
        List<GraphPart> stopPart2=new ArrayList<>(stopPart);
        if ((!isEmpty) && (next != null)) {
          stopPart2.add(next);
        }
        List<GraphTargetItem> onTrue=new ArrayList<>();
        if (!isEmpty && hasOntrue) {
          onTrue=printGraph(partCodes,partCodePos,visited,prepareBranchLocalData(localData),trueStack,allParts,part,nps.get(1),stopPart2,loops,null,staticOperation,path,recursionLevel + 1);
        }
        List<GraphTargetItem> onFalse=new ArrayList<>();
        if (!isEmpty && hasOnFalse) {
          onFalse=printGraph(partCodes,partCodePos,visited,prepareBranchLocalData(localData),falseStack,allParts,part,nps.get(0),stopPart2,loops,null,staticOperation,path,recursionLevel + 1);
        }
        makeAllCommands(onTrue,trueStack);
        makeAllCommands(onFalse,falseStack);
        if (!isEmpty(onTrue) && !isEmpty(onFalse) && onTrue.size() == 1 && onFalse.size() == 1 && (onTrue.get(0) instanceof PushItem) && (onFalse.get(0) instanceof PushItem)) {
          stack.push(new TernarOpItem(null,expr.invert(null),((PushItem)onTrue.get(0)).value,((PushItem)onFalse.get(0)).value));
        }
 else {
          boolean isIf=true;
          if (!stack.isEmpty() && onFalse.isEmpty() && onTrue.size() == 2 && (onTrue.get(0) instanceof PopItem) && (onTrue.get(1) instanceof PushItem)) {
            GraphTargetItem prevExpr=stack.pop();
            GraphTargetItem leftSide=expr;
            GraphTargetItem rightSide=((PushItem)onTrue.get(1)).value;
            if (leftSide instanceof DuplicateItem) {
              isIf=false;
              stack.push(new OrItem(null,prevExpr,rightSide));
            }
 else             if (leftSide.invert(null) instanceof DuplicateItem) {
              isIf=false;
              stack.push(new AndItem(null,prevExpr,rightSide));
            }
 else             if (prevExpr instanceof FalseItem) {
              isIf=false;
              stack.push(new OrItem(null,leftSide,rightSide));
            }
 else             if (prevExpr instanceof TrueItem) {
              isIf=false;
              stack.push(new AndItem(null,leftSide,rightSide));
            }
 else {
            }
          }
          if (isIf) {
            makeAllCommands(currentRet,stack);
            IfItem b=new IfItem(null,expr.invert(null),onTrue,onFalse);
            currentRet.add(b);
            if (processSubBlk(b,null)) {
              stack.push(new PopItem(null));
            }
          }
        }
        if (next != null) {
          printGraph(partCodes,partCodePos,visited,localData,stack,allParts,part,next,stopPart,loops,currentRet,staticOperation,path,recursionLevel + 1);
        }
      }
    }
    if (part.nextParts.size() == 1) {
      nextOnePart=part.nextParts.get(0);
    }
    if (nextOnePart != null) {
      printGraph(partCodes,partCodePos,visited,localData,stack,allParts,part,part.nextParts.get(0),stopPart,loops,currentRet,staticOperation,path,recursionLevel + 1);
    }
  }
  if (isLoop) {
    LoopItem li=loopItem;
    boolean loopTypeFound=false;
    boolean hasContinue=false;
    processIfs(loopItem.commands);
    checkContinueAtTheEnd(loopItem.commands,currentLoop);
    List<ContinueItem> continues=loopItem.getContinues();
    for (    ContinueItem c : continues) {
      if (c.loopId == currentLoop.id) {
        hasContinue=true;
        break;
      }
    }
    if (!hasContinue) {
      if (currentLoop.loopPreContinue != null) {
        List<GraphPart> stopContPart=new ArrayList<>();
        stopContPart.add(currentLoop.loopContinue);
        GraphPart precoBackup=currentLoop.loopPreContinue;
        currentLoop.loopPreContinue=null;
        loopItem.commands.addAll(printGraph(partCodes,partCodePos,visited,localData,new TranslateStack(path),allParts,null,precoBackup,stopContPart,loops,null,staticOperation,path,recursionLevel + 1));
      }
    }
    if (!loopTypeFound && (!loopItem.commands.isEmpty())) {
      if (loopItem.commands.get(0) instanceof IfItem) {
        IfItem ifi=(IfItem)loopItem.commands.get(0);
        List<GraphTargetItem> bodyBranch=null;
        boolean inverted=false;
        boolean breakpos2=false;
        if ((ifi.onTrue.size() == 1) && (ifi.onTrue.get(0) instanceof BreakItem)) {
          BreakItem bi=(BreakItem)ifi.onTrue.get(0);
          if (bi.loopId == currentLoop.id) {
            bodyBranch=ifi.onFalse;
            inverted=true;
          }
        }
 else         if ((ifi.onFalse.size() == 1) && (ifi.onFalse.get(0) instanceof BreakItem)) {
          BreakItem bi=(BreakItem)ifi.onFalse.get(0);
          if (bi.loopId == currentLoop.id) {
            bodyBranch=ifi.onTrue;
          }
        }
 else         if (loopItem.commands.size() == 2 && (loopItem.commands.get(1) instanceof BreakItem)) {
          BreakItem bi=(BreakItem)loopItem.commands.get(1);
          if (bi.loopId == currentLoop.id) {
            if (ifi.onTrue.isEmpty()) {
              inverted=true;
            }
            bodyBranch=inverted ? ifi.onFalse : ifi.onTrue;
            breakpos2=true;
          }
        }
        if (bodyBranch != null) {
          int index=ret.indexOf(loopItem);
          ret.remove(index);
          List<GraphTargetItem> exprList=new ArrayList<>();
          GraphTargetItem expr=ifi.expression;
          if (inverted) {
            if (expr instanceof LogicalOpItem) {
              expr=((LogicalOpItem)expr).invert(null);
            }
 else {
              expr=new NotItem(null,expr);
            }
          }
          exprList.add(expr);
          List<GraphTargetItem> commands=new ArrayList<>();
          commands.addAll(bodyBranch);
          loopItem.commands.remove(0);
          if (breakpos2) {
            loopItem.commands.remove(0);
          }
          commands.addAll(loopItem.commands);
          checkContinueAtTheEnd(commands,currentLoop);
          List<GraphTargetItem> finalComm=new ArrayList<>();
          if (currentLoop.loopPreContinue != null) {
            GraphPart backup=currentLoop.loopPreContinue;
            currentLoop.loopPreContinue=null;
            List<GraphPart> stopPart2=new ArrayList<>(stopPart);
            stopPart2.add(currentLoop.loopContinue);
            finalComm=printGraph(partCodes,partCodePos,visited,localData,new TranslateStack(path),allParts,null,backup,stopPart2,loops,null,staticOperation,path,recursionLevel + 1);
            currentLoop.loopPreContinue=backup;
            checkContinueAtTheEnd(finalComm,currentLoop);
          }
          if (!finalComm.isEmpty()) {
            ret.add(index,li=new ForItem(expr.src,currentLoop,new ArrayList<>(),exprList.get(exprList.size() - 1),finalComm,commands));
          }
 else {
            ret.add(index,li=new WhileItem(expr.src,currentLoop,exprList,commands));
          }
          loopTypeFound=true;
        }
      }
    }
    if (!loopTypeFound && (!loopItem.commands.isEmpty())) {
      if (loopItem.commands.get(loopItem.commands.size() - 1) instanceof IfItem) {
        IfItem ifi=(IfItem)loopItem.commands.get(loopItem.commands.size() - 1);
        List<GraphTargetItem> bodyBranch=null;
        boolean inverted=false;
        if ((ifi.onTrue.size() == 1) && (ifi.onTrue.get(0) instanceof BreakItem)) {
          BreakItem bi=(BreakItem)ifi.onTrue.get(0);
          if (bi.loopId == currentLoop.id) {
            bodyBranch=ifi.onFalse;
            inverted=true;
          }
        }
 else         if ((ifi.onFalse.size() == 1) && (ifi.onFalse.get(0) instanceof BreakItem)) {
          BreakItem bi=(BreakItem)ifi.onFalse.get(0);
          if (bi.loopId == currentLoop.id) {
            bodyBranch=ifi.onTrue;
          }
        }
        if (bodyBranch != null) {
          int index=ret.indexOf(loopItem);
          ret.remove(index);
          List<GraphTargetItem> exprList=new ArrayList<>();
          GraphTargetItem expr=ifi.expression;
          if (inverted) {
            expr=expr.invert(null);
          }
          checkContinueAtTheEnd(bodyBranch,currentLoop);
          List<GraphTargetItem> commands=new ArrayList<>();
          if (!bodyBranch.isEmpty()) {
            ret.add(index,loopItem);
          }
 else {
            loopItem.commands.remove(loopItem.commands.size() - 1);
            commands.addAll(loopItem.commands);
            commands.addAll(bodyBranch);
            exprList.add(expr);
            checkContinueAtTheEnd(commands,currentLoop);
            ret.add(index,li=new DoWhileItem(null,currentLoop,commands,exprList));
          }
          loopTypeFound=true;
        }
      }
    }
    if (!loopTypeFound) {
      if (currentLoop.loopPreContinue != null) {
        loopTypeFound=true;
        GraphPart backup=currentLoop.loopPreContinue;
        currentLoop.loopPreContinue=null;
        List<GraphPart> stopPart2=new ArrayList<>(stopPart);
        stopPart2.add(currentLoop.loopContinue);
        List<GraphTargetItem> finalComm=printGraph(partCodes,partCodePos,visited,localData,new TranslateStack(path),allParts,null,backup,stopPart2,loops,null,staticOperation,path,recursionLevel + 1);
        currentLoop.loopPreContinue=backup;
        checkContinueAtTheEnd(finalComm,currentLoop);
        if (!finalComm.isEmpty()) {
          if (finalComm.get(finalComm.size() - 1) instanceof IfItem) {
            IfItem ifi=(IfItem)finalComm.get(finalComm.size() - 1);
            boolean ok=false;
            boolean invert=false;
            if (((ifi.onTrue.size() == 1) && (ifi.onTrue.get(0) instanceof BreakItem) && (((BreakItem)ifi.onTrue.get(0)).loopId == currentLoop.id)) && ((ifi.onTrue.size() == 1) && (ifi.onFalse.get(0) instanceof ContinueItem) && (((ContinueItem)ifi.onFalse.get(0)).loopId == currentLoop.id))) {
              ok=true;
              invert=true;
            }
            if (((ifi.onTrue.size() == 1) && (ifi.onTrue.get(0) instanceof ContinueItem) && (((ContinueItem)ifi.onTrue.get(0)).loopId == currentLoop.id)) && ((ifi.onTrue.size() == 1) && (ifi.onFalse.get(0) instanceof BreakItem) && (((BreakItem)ifi.onFalse.get(0)).loopId == currentLoop.id))) {
              ok=true;
            }
            if (ok) {
              finalComm.remove(finalComm.size() - 1);
              int index=ret.indexOf(loopItem);
              ret.remove(index);
              List<GraphTargetItem> exprList=new ArrayList<>(finalComm);
              GraphTargetItem expr=ifi.expression;
              if (invert) {
                expr=expr.invert(null);
              }
              exprList.add(expr);
              ret.add(index,li=new DoWhileItem(null,currentLoop,loopItem.commands,exprList));
            }
          }
        }
      }
    }
    if (!loopTypeFound) {
      checkContinueAtTheEnd(loopItem.commands,currentLoop);
    }
    currentLoop.phase=2;
    GraphTargetItem replaced=checkLoop(li,localData,loops);
    if (replaced != li) {
      int index=ret.indexOf(li);
      ret.remove(index);
      if (replaced != null) {
        ret.add(index,replaced);
      }
    }
    if (currentLoop.loopBreak != null) {
      ret.addAll(printGraph(partCodes,partCodePos,visited,localData,sPreLoop,allParts,part,currentLoop.loopBreak,stopPart,loops,null,staticOperation,path,recursionLevel + 1));
    }
  }
  return ret;
}

Fixed version (ground truth):
protected List<GraphTargetItem> printGraph(Map<GraphPart,List<GraphTargetItem>> partCodes,Map<GraphPart,Integer> partCodePos,List<GraphPart> visited,BaseLocalData localData,TranslateStack stack,List<GraphPart> allParts,GraphPart parent,GraphPart part,List<GraphPart> stopPart,List<Loop> loops,List<GraphTargetItem> ret,int staticOperation,String path,int recursionLevel) throws InterruptedException {
  if (Thread.currentThread().isInterrupted()) {
    throw new InterruptedException();
  }
  if (stopPart == null) {
    stopPart=new ArrayList<>();
  }
  if (recursionLevel > allParts.size() + 1) {
    throw new TranslateException("String_Node_Str");
  }
  if (ret == null) {
    ret=new ArrayList<>();
  }
  boolean debugMode=false;
  if (debugMode) {
    System.err.println("String_Node_Str" + part + "String_Node_Str"+ part.nextParts.size());
  }
  if (part == null) {
    return ret;
  }
  part=checkPart(stack,localData,part,allParts);
  if (part == null) {
    return ret;
  }
  if (part.ignored) {
    return ret;
  }
  List<GraphPart> loopContinues=getLoopsContinues(loops);
  boolean isLoop=false;
  Loop currentLoop=null;
  for (  Loop el : loops) {
    if ((el.loopContinue == part) && (el.phase == 0)) {
      currentLoop=el;
      currentLoop.phase=1;
      isLoop=true;
      break;
    }
  }
  if (debugMode) {
    System.err.println("String_Node_Str" + loops.size());
  }
  for (int l=loops.size() - 1; l >= 0; l--) {
    Loop el=loops.get(l);
    if (el == currentLoop) {
      if (debugMode) {
        System.err.println("String_Node_Str" + el);
      }
      continue;
    }
    if (el.phase != 1) {
      if (debugMode) {
        System.err.println("String_Node_Str" + el);
      }
      continue;
    }
    if (el.loopBreak == part) {
      if (currentLoop != null) {
        currentLoop.phase=0;
      }
      if (debugMode) {
        System.err.println("String_Node_Str");
      }
      ret.add(new BreakItem(null,el.id));
      return ret;
    }
    if (el.loopPreContinue == part) {
      if (currentLoop != null) {
        currentLoop.phase=0;
      }
      if (debugMode) {
        System.err.println("String_Node_Str");
      }
      ret.add(new ContinueItem(null,el.id));
      return ret;
    }
    if (el.loopContinue == part) {
      if (currentLoop != null) {
        currentLoop.phase=0;
      }
      if (debugMode) {
        System.err.println("String_Node_Str");
      }
      ret.add(new ContinueItem(null,el.id));
      return ret;
    }
  }
  if (stopPart.contains(part)) {
    if (currentLoop != null) {
      currentLoop.phase=0;
    }
    if (debugMode) {
      System.err.println("String_Node_Str" + part);
    }
    return ret;
  }
  if ((part != null) && (code.size() <= part.start)) {
    ret.add(new ScriptEndItem());
    return ret;
  }
  if (visited.contains(part)) {
    String labelName="String_Node_Str" + part.start;
    List<GraphTargetItem> firstCode=partCodes.get(part);
    int firstCodePos=partCodePos.get(part);
    if (firstCodePos > firstCode.size()) {
      firstCodePos=firstCode.size();
    }
    if (firstCode.size() > firstCodePos && (firstCode.get(firstCodePos) instanceof LabelItem)) {
      labelName=((LabelItem)firstCode.get(firstCodePos)).labelName;
    }
 else {
      firstCode.add(firstCodePos,new LabelItem(null,labelName));
    }
    ret.add(new GotoItem(null,labelName));
    return ret;
  }
 else {
    visited.add(part);
    partCodes.put(part,ret);
    partCodePos.put(part,ret.size());
  }
  List<GraphTargetItem> currentRet=ret;
  UniversalLoopItem loopItem=null;
  TranslateStack sPreLoop=stack;
  if (isLoop) {
    stack=(TranslateStack)stack.clone();
    stack.clear();
    loopItem=new UniversalLoopItem(null,currentLoop);
    currentRet.add(loopItem);
    loopItem.commands=new ArrayList<>();
    currentRet=loopItem.commands;
  }
  boolean parseNext=true;
  List<GraphTargetItem> output=new ArrayList<>();
  List<GraphPart> parts=new ArrayList<>();
  if (part instanceof GraphPartMulti) {
    parts=((GraphPartMulti)part).parts;
  }
 else {
    parts.add(part);
  }
  for (  GraphPart p : parts) {
    int end=p.end;
    int start=p.start;
    output.addAll(code.translatePart(p,localData,stack,start,end,staticOperation,path));
    if ((end >= code.size() - 1) && p.nextParts.isEmpty()) {
      output.add(new ScriptEndItem());
    }
  }
  if (parseNext) {
    List<GraphTargetItem> retCheck=check(partCodes,partCodePos,code,localData,allParts,stack,parent,part,stopPart,loops,output,currentLoop,staticOperation,path);
    if (retCheck != null) {
      if (!retCheck.isEmpty()) {
        currentRet.addAll(retCheck);
      }
      parseNext=false;
    }
 else {
      currentRet.addAll(output);
    }
  }
  if (parseNext) {
    if (part.nextParts.size() > 2) {
      GraphPart next=getMostCommonPart(localData,part.nextParts,loops);
      List<GraphPart> vis=new ArrayList<>();
      GraphTargetItem switchedItem=stack.pop();
      makeAllCommands(currentRet,stack);
      List<GraphTargetItem> caseValues=new ArrayList<>();
      List<List<GraphTargetItem>> caseCommands=new ArrayList<>();
      List<GraphTargetItem> defaultCommands=new ArrayList<>();
      List<Integer> valueMappings=new ArrayList<>();
      Loop swLoop=new Loop(loops.size(),null,next);
      swLoop.phase=1;
      loops.add(swLoop);
      boolean first=false;
      int pos=0;
      Map<Integer,GraphTargetItem> caseExpressions=new HashMap<>();
      Map<Integer,GraphTargetItem> caseExpressionLeftSides=new HashMap<>();
      Map<Integer,GraphTargetItem> caseExpressionRightSides=new HashMap<>();
      GraphTargetItem it=switchedItem;
      int defaultBranch=0;
      boolean hasExpr=false;
      while (it instanceof TernarOpItem) {
        TernarOpItem to=(TernarOpItem)it;
        if (to.expression instanceof EqualsTypeItem) {
          if (to.onTrue instanceof IntegerValueTypeItem) {
            int cpos=((IntegerValueTypeItem)to.onTrue).intValue();
            caseExpressionLeftSides.put(cpos,((EqualsTypeItem)to.expression).getLeftSide());
            caseExpressionRightSides.put(cpos,((EqualsTypeItem)to.expression).getRightSide());
            it=to.onFalse;
          }
 else {
            break;
          }
        }
 else {
          break;
        }
      }
      if (it instanceof IntegerValueTypeItem) {
        defaultBranch=((IntegerValueTypeItem)it).intValue();
      }
      if (!caseExpressionRightSides.isEmpty()) {
        GraphTargetItem firstItem;
        firstItem=(GraphTargetItem)caseExpressionRightSides.values().toArray()[0];
        boolean sameRight=true;
        for (        GraphTargetItem cit : caseExpressionRightSides.values()) {
          if (!cit.equals(firstItem)) {
            sameRight=false;
            break;
          }
        }
        if (sameRight) {
          caseExpressions=caseExpressionLeftSides;
          switchedItem=firstItem;
          hasExpr=true;
        }
 else {
          firstItem=(GraphTargetItem)caseExpressionLeftSides.values().toArray()[0];
          boolean sameLeft=true;
          for (          GraphTargetItem cit : caseExpressionLeftSides.values()) {
            if (!cit.equals(firstItem)) {
              sameLeft=false;
              break;
            }
          }
          if (sameLeft) {
            caseExpressions=caseExpressionRightSides;
            switchedItem=firstItem;
            hasExpr=true;
          }
        }
      }
      first=true;
      pos=0;
      GraphPart defaultPart=hasExpr ? part.nextParts.get(1 + defaultBranch) : part.nextParts.get(0);
      for (      GraphPart p : part.nextParts) {
        if (p != defaultPart) {
          if (caseExpressions.containsKey(pos)) {
            caseValues.add(caseExpressions.get(pos));
          }
 else {
            caseValues.add(new IntegerValueItem(null,pos));
          }
          pos++;
        }
      }
      first=true;
      pos=0;
      List<GraphTargetItem> nextCommands=new ArrayList<>();
      for (      GraphPart p : part.nextParts) {
        if (p != defaultPart) {
          if (vis.contains(p)) {
            valueMappings.add(caseCommands.size() - 1);
            continue;
          }
          valueMappings.add(caseCommands.size());
        }
        List<GraphPart> stopPart2=new ArrayList<>();
        if (next != null) {
          stopPart2.add(next);
        }
 else         if (!stopPart.isEmpty()) {
          stopPart2.add(stopPart.get(stopPart.size() - 1));
        }
        for (        GraphPart p2 : part.nextParts) {
          if (p2 == p) {
            continue;
          }
          if (!stopPart2.contains(p2)) {
            stopPart2.add(p2);
          }
        }
        if (next != p) {
          if (p == defaultPart && !defaultCommands.isEmpty()) {
          }
 else {
            TranslateStack s2=(TranslateStack)stack.clone();
            s2.clear();
            nextCommands=printGraph(partCodes,partCodePos,visited,prepareBranchLocalData(localData),s2,allParts,part,p,stopPart2,loops,null,staticOperation,path,recursionLevel + 1);
            makeAllCommands(nextCommands,s2);
            if (p == defaultPart) {
              defaultCommands=nextCommands;
            }
 else {
              caseCommands.add(nextCommands);
            }
            vis.add(p);
          }
        }
 else {
          if (p == defaultPart) {
            defaultCommands=nextCommands;
          }
 else {
            caseCommands.add(nextCommands);
          }
        }
        first=false;
        pos++;
      }
      if (!defaultCommands.isEmpty() && (defaultCommands.get(defaultCommands.size() - 1) instanceof BreakItem)) {
        BreakItem bi=(BreakItem)defaultCommands.get(defaultCommands.size() - 1);
        if (bi.loopId == swLoop.id) {
          defaultCommands.remove(defaultCommands.size() - 1);
        }
      }
      SwitchItem sw=new SwitchItem(null,swLoop,switchedItem,caseValues,caseCommands,defaultCommands,valueMappings);
      currentRet.add(sw);
      swLoop.phase=2;
      if (next != null) {
        currentRet.addAll(printGraph(partCodes,partCodePos,visited,localData,stack,allParts,part,next,stopPart,loops,null,staticOperation,path,recursionLevel + 1));
      }
      pos++;
    }
    GraphPart nextOnePart=null;
    if (part.nextParts.size() == 2) {
      GraphTargetItem expr=stack.pop();
      if (nextOnePart == null) {
        List<GraphPart> nps;
        nps=part.nextParts;
        boolean isEmpty=nps.get(0) == nps.get(1);
        GraphPart next=getCommonPart(localData,nps,loops);
        TranslateStack trueStack=(TranslateStack)stack.clone();
        TranslateStack falseStack=(TranslateStack)stack.clone();
        trueStack.clear();
        falseStack.clear();
        if (isEmpty) {
          next=nps.get(0);
        }
        boolean hasOntrue=nps.get(1) != next;
        boolean hasOnFalse=nps.get(0) != next;
        List<GraphPart> stopPart2=new ArrayList<>(stopPart);
        if ((!isEmpty) && (next != null)) {
          stopPart2.add(next);
        }
        List<GraphTargetItem> onTrue=new ArrayList<>();
        if (!isEmpty && hasOntrue) {
          onTrue=printGraph(partCodes,partCodePos,visited,prepareBranchLocalData(localData),trueStack,allParts,part,nps.get(1),stopPart2,loops,null,staticOperation,path,recursionLevel + 1);
        }
        List<GraphTargetItem> onFalse=new ArrayList<>();
        if (!isEmpty && hasOnFalse) {
          onFalse=printGraph(partCodes,partCodePos,visited,prepareBranchLocalData(localData),falseStack,allParts,part,nps.get(0),stopPart2,loops,null,staticOperation,path,recursionLevel + 1);
        }
        makeAllCommands(onTrue,trueStack);
        makeAllCommands(onFalse,falseStack);
        if (!isEmpty(onTrue) && !isEmpty(onFalse) && onTrue.size() == 1 && onFalse.size() == 1 && (onTrue.get(0) instanceof PushItem) && (onFalse.get(0) instanceof PushItem)) {
          stack.push(new TernarOpItem(null,expr.invert(null),((PushItem)onTrue.get(0)).value,((PushItem)onFalse.get(0)).value));
        }
 else {
          boolean isIf=true;
          if (!stack.isEmpty() && onFalse.isEmpty() && onTrue.size() == 2 && (onTrue.get(0) instanceof PopItem) && (onTrue.get(1) instanceof PushItem)) {
            GraphTargetItem prevExpr=stack.pop();
            GraphTargetItem leftSide=expr;
            GraphTargetItem rightSide=((PushItem)onTrue.get(1)).value;
            if (leftSide instanceof DuplicateItem) {
              isIf=false;
              stack.push(new OrItem(null,prevExpr,rightSide));
            }
 else             if (leftSide.invert(null) instanceof DuplicateItem) {
              isIf=false;
              stack.push(new AndItem(null,prevExpr,rightSide));
            }
 else             if (prevExpr instanceof FalseItem) {
              isIf=false;
              stack.push(new OrItem(null,leftSide,rightSide));
            }
 else             if (prevExpr instanceof TrueItem) {
              isIf=false;
              stack.push(new AndItem(null,leftSide,rightSide));
            }
 else {
            }
          }
          if (isIf) {
            makeAllCommands(currentRet,stack);
            IfItem b=new IfItem(null,expr.invert(null),onTrue,onFalse);
            currentRet.add(b);
            if (processSubBlk(b,null)) {
              stack.push(new PopItem(null));
            }
          }
        }
        if (next != null) {
          printGraph(partCodes,partCodePos,visited,localData,stack,allParts,part,next,stopPart,loops,currentRet,staticOperation,path,recursionLevel + 1);
        }
      }
    }
    if (part.nextParts.size() == 1) {
      nextOnePart=part.nextParts.get(0);
    }
    if (nextOnePart != null) {
      printGraph(partCodes,partCodePos,visited,localData,stack,allParts,part,part.nextParts.get(0),stopPart,loops,currentRet,staticOperation,path,recursionLevel + 1);
    }
  }
  if (isLoop) {
    LoopItem li=loopItem;
    boolean loopTypeFound=false;
    boolean hasContinue=false;
    processIfs(loopItem.commands);
    checkContinueAtTheEnd(loopItem.commands,currentLoop);
    List<ContinueItem> continues=loopItem.getContinues();
    for (    ContinueItem c : continues) {
      if (c.loopId == currentLoop.id) {
        hasContinue=true;
        break;
      }
    }
    if (!hasContinue) {
      if (currentLoop.loopPreContinue != null) {
        List<GraphPart> stopContPart=new ArrayList<>();
        stopContPart.add(currentLoop.loopContinue);
        GraphPart precoBackup=currentLoop.loopPreContinue;
        currentLoop.loopPreContinue=null;
        loopItem.commands.addAll(printGraph(partCodes,partCodePos,visited,localData,new TranslateStack(path),allParts,null,precoBackup,stopContPart,loops,null,staticOperation,path,recursionLevel + 1));
      }
    }
    if (!loopTypeFound && (!loopItem.commands.isEmpty())) {
      if (loopItem.commands.get(0) instanceof IfItem) {
        IfItem ifi=(IfItem)loopItem.commands.get(0);
        List<GraphTargetItem> bodyBranch=null;
        boolean inverted=false;
        boolean breakpos2=false;
        if ((ifi.onTrue.size() == 1) && (ifi.onTrue.get(0) instanceof BreakItem)) {
          BreakItem bi=(BreakItem)ifi.onTrue.get(0);
          if (bi.loopId == currentLoop.id) {
            bodyBranch=ifi.onFalse;
            inverted=true;
          }
        }
 else         if ((ifi.onFalse.size() == 1) && (ifi.onFalse.get(0) instanceof BreakItem)) {
          BreakItem bi=(BreakItem)ifi.onFalse.get(0);
          if (bi.loopId == currentLoop.id) {
            bodyBranch=ifi.onTrue;
          }
        }
 else         if (loopItem.commands.size() == 2 && (loopItem.commands.get(1) instanceof BreakItem)) {
          BreakItem bi=(BreakItem)loopItem.commands.get(1);
          if (bi.loopId == currentLoop.id) {
            if (ifi.onTrue.isEmpty()) {
              inverted=true;
            }
            bodyBranch=inverted ? ifi.onFalse : ifi.onTrue;
            breakpos2=true;
          }
        }
        if (bodyBranch != null) {
          int index=ret.indexOf(loopItem);
          ret.remove(index);
          List<GraphTargetItem> exprList=new ArrayList<>();
          GraphTargetItem expr=ifi.expression;
          if (inverted) {
            if (expr instanceof LogicalOpItem) {
              expr=((LogicalOpItem)expr).invert(null);
            }
 else {
              expr=new NotItem(null,expr);
            }
          }
          exprList.add(expr);
          List<GraphTargetItem> commands=new ArrayList<>();
          commands.addAll(bodyBranch);
          loopItem.commands.remove(0);
          if (breakpos2) {
            loopItem.commands.remove(0);
          }
          commands.addAll(loopItem.commands);
          checkContinueAtTheEnd(commands,currentLoop);
          List<GraphTargetItem> finalComm=new ArrayList<>();
          if (currentLoop.loopPreContinue != null) {
            GraphPart backup=currentLoop.loopPreContinue;
            currentLoop.loopPreContinue=null;
            List<GraphPart> stopPart2=new ArrayList<>(stopPart);
            stopPart2.add(currentLoop.loopContinue);
            finalComm=printGraph(partCodes,partCodePos,visited,localData,new TranslateStack(path),allParts,null,backup,stopPart2,loops,null,staticOperation,path,recursionLevel + 1);
            currentLoop.loopPreContinue=backup;
            checkContinueAtTheEnd(finalComm,currentLoop);
          }
          if (!finalComm.isEmpty()) {
            ret.add(index,li=new ForItem(expr.src,currentLoop,new ArrayList<>(),exprList.get(exprList.size() - 1),finalComm,commands));
          }
 else {
            ret.add(index,li=new WhileItem(expr.src,currentLoop,exprList,commands));
          }
          loopTypeFound=true;
        }
      }
    }
    if (!loopTypeFound && (!loopItem.commands.isEmpty())) {
      if (loopItem.commands.get(loopItem.commands.size() - 1) instanceof IfItem) {
        IfItem ifi=(IfItem)loopItem.commands.get(loopItem.commands.size() - 1);
        List<GraphTargetItem> bodyBranch=null;
        boolean inverted=false;
        if ((ifi.onTrue.size() == 1) && (ifi.onTrue.get(0) instanceof BreakItem)) {
          BreakItem bi=(BreakItem)ifi.onTrue.get(0);
          if (bi.loopId == currentLoop.id) {
            bodyBranch=ifi.onFalse;
            inverted=true;
          }
        }
 else         if ((ifi.onFalse.size() == 1) && (ifi.onFalse.get(0) instanceof BreakItem)) {
          BreakItem bi=(BreakItem)ifi.onFalse.get(0);
          if (bi.loopId == currentLoop.id) {
            bodyBranch=ifi.onTrue;
          }
        }
        if (bodyBranch != null) {
          int index=ret.indexOf(loopItem);
          ret.remove(index);
          List<GraphTargetItem> exprList=new ArrayList<>();
          GraphTargetItem expr=ifi.expression;
          if (inverted) {
            expr=expr.invert(null);
          }
          checkContinueAtTheEnd(bodyBranch,currentLoop);
          List<GraphTargetItem> commands=new ArrayList<>();
          if (!bodyBranch.isEmpty()) {
            ret.add(index,loopItem);
          }
 else {
            loopItem.commands.remove(loopItem.commands.size() - 1);
            commands.addAll(loopItem.commands);
            commands.addAll(bodyBranch);
            exprList.add(expr);
            checkContinueAtTheEnd(commands,currentLoop);
            ret.add(index,li=new DoWhileItem(null,currentLoop,commands,exprList));
          }
          loopTypeFound=true;
        }
      }
    }
    if (!loopTypeFound) {
      if (currentLoop.loopPreContinue != null) {
        loopTypeFound=true;
        GraphPart backup=currentLoop.loopPreContinue;
        currentLoop.loopPreContinue=null;
        List<GraphPart> stopPart2=new ArrayList<>(stopPart);
        stopPart2.add(currentLoop.loopContinue);
        List<GraphTargetItem> finalComm=printGraph(partCodes,partCodePos,visited,localData,new TranslateStack(path),allParts,null,backup,stopPart2,loops,null,staticOperation,path,recursionLevel + 1);
        currentLoop.loopPreContinue=backup;
        checkContinueAtTheEnd(finalComm,currentLoop);
        if (!finalComm.isEmpty()) {
          if (finalComm.get(finalComm.size() - 1) instanceof IfItem) {
            IfItem ifi=(IfItem)finalComm.get(finalComm.size() - 1);
            boolean ok=false;
            boolean invert=false;
            if (((ifi.onTrue.size() == 1) && (ifi.onTrue.get(0) instanceof BreakItem) && (((BreakItem)ifi.onTrue.get(0)).loopId == currentLoop.id)) && ((ifi.onFalse.size() == 1) && (ifi.onFalse.get(0) instanceof ContinueItem) && (((ContinueItem)ifi.onFalse.get(0)).loopId == currentLoop.id))) {
              ok=true;
              invert=true;
            }
            if (((ifi.onTrue.size() == 1) && (ifi.onTrue.get(0) instanceof ContinueItem) && (((ContinueItem)ifi.onTrue.get(0)).loopId == currentLoop.id)) && ((ifi.onFalse.size() == 1) && (ifi.onFalse.get(0) instanceof BreakItem) && (((BreakItem)ifi.onFalse.get(0)).loopId == currentLoop.id))) {
              ok=true;
            }
            if (ok) {
              finalComm.remove(finalComm.size() - 1);
              int index=ret.indexOf(loopItem);
              ret.remove(index);
              List<GraphTargetItem> exprList=new ArrayList<>(finalComm);
              GraphTargetItem expr=ifi.expression;
              if (invert) {
                expr=expr.invert(null);
              }
              exprList.add(expr);
              ret.add(index,li=new DoWhileItem(null,currentLoop,loopItem.commands,exprList));
            }
          }
        }
      }
    }
    if (!loopTypeFound) {
      checkContinueAtTheEnd(loopItem.commands,currentLoop);
    }
    currentLoop.phase=2;
    GraphTargetItem replaced=checkLoop(li,localData,loops);
    if (replaced != li) {
      int index=ret.indexOf(li);
      ret.remove(index);
      if (replaced != null) {
        ret.add(index,replaced);
      }
    }
    if (currentLoop.loopBreak != null) {
      ret.addAll(printGraph(partCodes,partCodePos,visited,localData,sPreLoop,allParts,part,currentLoop.loopBreak,stopPart,loops,null,staticOperation,path,recursionLevel + 1));
    }
  }
  return ret;
}