@Test
  public void testRemoveGetTimeAndIncrement() {
    String actionsString =
        "ConstantPool \"a\"\n"
            + "GetTime\n"
            + "Increment\n"
            + "If loc1\n"
            + "Push \"FAIL\"\n"
            + "Trace\n"
            + "loc1:Push \"OK\"\n"
            + "Trace\n"
            + "loc2:";
    try {
      List<Action> actions = ASMParser.parse(0, true, actionsString, swf.version, false);

      DoActionTag doa = getFirstActionTag();
      doa.setActionBytes(Action.actionsToBytes(actions, true, swf.version));
      HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false);
      Action.actionsToSource(doa, doa.getActions(), "", writer);
      String actualResult = writer.toString();

      assertTrue(!actualResult.contains("FAIL"));
      assertTrue(actualResult.contains("OK"));
    } catch (IOException | ActionParseException | InterruptedException ex) {
      fail();
    }
  }
 private void compareSrc(int frame, String expectedResult) {
   DoActionTag doa = getFrameSource(frame);
   assertNotNull(doa);
   HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false);
   try {
     Action.actionsToSource(doa, doa.getActions(), "", writer);
   } catch (InterruptedException ex) {
     fail();
   }
   String actualResult = cleanPCode(writer.toString());
   expectedResult = cleanPCode(expectedResult);
   assertEquals(actualResult, expectedResult);
 }
 private String recompile(String str)
     throws ActionParseException, IOException, CompilationException, InterruptedException,
         TimeoutException {
   ActionScriptParser par = new ActionScriptParser(SWF.DEFAULT_VERSION);
   HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false);
   List<Action> actions = par.actionsFromString(str);
   byte[] hex = Action.actionsToBytes(actions, true, SWF.DEFAULT_VERSION);
   ActionList list =
       ActionListReader.readActionListTimeout(
           new ArrayList<DisassemblyListener>(),
           new SWFInputStream(swf, hex),
           SWF.DEFAULT_VERSION,
           0,
           hex.length,
           "");
   Action.actionsToSource(null, list, "", writer);
   return writer.toString();
 }
  @Test
  public void testRemoveJumpsToTheNextAction() {
    String actionsString =
        "ConstantPool \"a\" \"b\" \"c\"\n"
            + "Push false register1\n"
            + "StoreRegister 2\n"
            + "Pop\n"
            + "Push register2\n"
            + "StoreRegister 0\n"
            + "Push \"a\"\n"
            + "StrictEquals\n"
            + "If loc005a\n"
            + "Push register0 \"b\"\n"
            + "StrictEquals\n"
            + "If loc0068\n"
            + "Jump loc0048;\n"
            + "loc0048:Push register0 \"c\"\n"
            + "StrictEquals\n"
            + "If loc0076\n"
            + "Jump loc0084\n"
            + "loc005a:Push 1\n"
            + "Trace\n"
            + "Jump loc0084\n"
            + "loc0068:Push 2\n"
            + "Trace\n"
            + "Jump loc0084\n"
            + "loc0076:Push 3\n"
            + "Trace\n"
            + "Jump loc0084\n"
            + "loc0084:";
    try {
      List<Action> actions = ASMParser.parse(0, true, actionsString, swf.version, false);

      DoActionTag doa = getFirstActionTag();
      doa.setActionBytes(Action.actionsToBytes(actions, true, swf.version));
      HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false);
      Action.actionsToSource(doa, doa.getActions(), "", writer);
      String actualResult = writer.toString();

      assertTrue(actualResult.contains("case \"c\":"));
    } catch (IOException | ActionParseException | InterruptedException ex) {
      fail();
    }
  }
  @Test(dataProvider = "provideFiles")
  public void testDirectEditing(String filePath)
      throws IOException, InterruptedException, AVM2ParseException, CompilationException {
    File playerSWC = Configuration.getPlayerSWC();
    if (playerSWC == null) {
      throw new IOException(
          "Player SWC library not found, please place it to " + Configuration.getFlashLibPath());
    }
    try {
      SWF swf = new SWF(new BufferedInputStream(new FileInputStream(filePath)), false);
      if (swf.isAS3()) {
        boolean dotest = false;
        List<ABC> allAbcs = new ArrayList<>();
        for (ABCContainerTag ct : swf.getAbcList()) {
          allAbcs.add(ct.getABC());
        }
        for (ABC abc : allAbcs) {
          for (int s = 0; s < abc.script_info.size(); s++) {
            String startAfter = null;
            HighlightedTextWriter htw = new HighlightedTextWriter(new CodeFormatting(), false);
            ScriptPack en = abc.script_info.get(s).getPacks(abc, s, null, allAbcs).get(0);
            String classPathString = en.getClassPath().toString();
            if (startAfter == null || classPathString.equals(startAfter)) {
              dotest = true;
            }
            if (!dotest) {
              System.out.println("Skipped:" + classPathString);
              continue;
            }

            System.out.println("Recompiling:" + classPathString + "...");
            en.toSource(htw, abc.script_info.get(s).traits.traits, ScriptExportMode.AS, false);
            String original = htw.toString();
            com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScriptParser.compile(
                original,
                abc,
                allAbcs,
                false,
                en.getClassPath().className + ".as",
                abc.instance_info.size());

            // remove last compiled script:
            abc.script_info.remove(abc.script_info.size() - 1);
          }
        }
      } else {
        Map<String, ASMSource> asms = swf.getASMs(false);

        for (ASMSource asm : asms.values()) {
          try {
            HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false);
            Action.actionsToSource(asm, asm.getActions(), asm.toString() /*FIXME?*/, writer);
            String as = writer.toString();
            as = asm.removePrefixAndSuffix(as);
            ActionScriptParser par = new ActionScriptParser(swf.version);
            try {
              asm.setActions(par.actionsFromString(as));
            } catch (ActionParseException | CompilationException ex) {
              fail("Unable to parse: " + as + "/" + asm.toString(), ex);
            }
            writer = new HighlightedTextWriter(new CodeFormatting(), false);
            Action.actionsToSource(asm, asm.getActions(), asm.toString() /*FIXME?*/, writer);
            String as2 = writer.toString();
            as2 = asm.removePrefixAndSuffix(as2);
            try {
              asm.setActions(par.actionsFromString(as2));
            } catch (ActionParseException | CompilationException ex) {
              fail(
                  "Unable to parse: " + asm.getSwf().getShortFileName() + "/" + asm.toString(), ex);
            }
            writer = new HighlightedTextWriter(new CodeFormatting(), false);
            Action.actionsToSource(asm, asm.getActions(), asm.toString() /*FIXME?*/, writer);
            String as3 = writer.toString();
            as3 = asm.removePrefixAndSuffix(as3);
            if (!as3.equals(as2)) {
              fail(
                  "ActionScript is different: "
                      + asm.getSwf().getShortFileName()
                      + "/"
                      + asm.toString());
            }
          } catch (InterruptedException
              | IOException
              | OutOfMemoryError
              | TranslateException
              | StackOverflowError ex) {
          }
        }
      }
    } catch (Exception ex) {
      fail("Exception during decompilation: " + filePath, ex);
    }
  }