public static void Print() {
   MinecraftSave save = ConverterMain.options.getsave(0);
   if (save != null) {
     if (ConverterMain.isdone.get("analyzesave") && ConverterMain.isdone.get("idmap0")) {
       for (int ntype = 0; ntype < ConverterMain.Ntype; ntype++) {
         Iterator it = save.listofidsinsave[ntype].iterator();
         while (it.hasNext()) {
           Object id = (Object) it.next();
           if (ConverterMain.idmaps[ntype].get(0).containsKey(id)) {
             Logger.logln(
                 save.nidsinsave[ntype].get(id)
                     + " "
                     + ConverterMain.typenames[ntype]
                     + " ID "
                     + id
                     + "("
                     + ConverterMain.idmaps[ntype].get(0).get(id)[0]
                     + ")");
           } else {
             Logger.logln("problem" + id);
             return;
           }
         }
       }
     }
   }
 }
  private static void count(int ntype, Object id0, Object id1, boolean convert) {
    // type=1  convert
    // type=-1 remove
    if (convert) {
      if (id1.equals(Integer.valueOf(-1))) {
        if (!id0.equals(id1) && !converteds[ntype].contains(id0)) {
          Logger.logln(
              currentmode
                  + " | Converting "
                  + ConverterMain.typenames[ntype]
                  + " ID: "
                  + id0
                  + " to "
                  + id1
                  + " in chunk "
                  + xc
                  + ","
                  + zc);
          converteds[ntype].add(id0);
          nconverteds[ntype].put(id0, 0);
        }
        if (!id0.equals(id1) && converteds[ntype].contains(id0)) {
          nconverteds[ntype].put(id0, nconverteds[ntype].get(id0) + 1);
        }
      }
      if (id1.equals(Integer.valueOf(-1))) {
        if (!problematicids[ntype].contains(id0)) {
          // Logger.logln("Found "+ConverterMain.typenames[ntype]+" ID :"+id0+" in the file that is
          // not in the converter map");
          // Logger.logln("      First seen in region "+currentregionname+" X "+xc+" Z "+zc);
          Logger.logln(
              currentmode + " | Removing " + ConverterMain.typenames[ntype] + " ID: " + id0);

          problematicids[ntype].add(id0);
        }
      }
    } else {
      if (!ConverterMain.options.getsave(0).listofidsinsave[ntype].contains(id0)) {
        ConverterMain.options.getsave(0).listofidsinsave[ntype].add(id0);
        ConverterMain.options.getsave(0).nidsinsave[ntype].put(id0, 1);
      } else {
        ConverterMain.options
            .getsave(0)
            .nidsinsave[ntype]
            .put(id0, ConverterMain.options.getsave(0).nidsinsave[ntype].get(id0) + 1);
      }
    }
  }
 @Override
 protected void execute() throws ExecutionException {
   Logger.logln("Computing the convert map....");
   Logger.level = 1;
   analyzeorconvert();
   Logger.level = 0;
 }
  public void analyzeorconvert() {
    // Doing the meat of the conversion. Assumes the ConverterMain.convertmap is done
    // HashMap<List<Integer>, List<Integer>> convertmap=ConverterMain.getInstance().convertmap;
    HashMap<Integer, Integer> convertermaps[] = new HashMap[2];

    File rootfolderorig = ConverterMain.options.getsave(0).getRootfolder();
    File rootfolderdest = ConverterMain.options.getsave(1).getRootfolder();
    File cachefile = ConverterMain.options.getsave(0).getcachefile();

    if (!rootfolderorig.exists() || !rootfolderdest.isDirectory()) {
      Logger.logln("ERROR with the provided save origin or destination");
      return;
    }
    try {
      // File rootfolderdestnew=new
      // File(rootfolderdest,rootfolderorig.getName()+"_convertedto_"+ConverterMain.options.getminecraftversion(1));
      if (convert) {
        if (new File(rootfolderdest, "level.dat").exists()) {
          int response =
              JOptionPane.showConfirmDialog(
                  null,
                  "there's already a converted save. Destroy it?",
                  "Confirm",
                  JOptionPane.YES_NO_OPTION,
                  JOptionPane.QUESTION_MESSAGE);
          if (response == JOptionPane.NO_OPTION || response == JOptionPane.CLOSED_OPTION) {
            Logger.logln("INFO Aborting conversion");
            return;
          }
          Logger.logln("WARNING there's already a converted save there. We will destroy it");
          rootfolderdest.delete();
        }

        try {
          copyDirectory(rootfolderorig, rootfolderdest);
        } catch (IOException e) {
          Logger.logln("ERROR copying data from the old to the new level folder");
          return;
        }
      } else {
        if (cachefile.exists() && !MainFrame.redoanalyzesaveCheck.isSelected()) {
          try {
            FileInputStream fis = new FileInputStream(cachefile);
            ObjectInputStream ois = new ObjectInputStream(fis);
            for (int ntype = 0; ntype < ConverterMain.Ntype; ntype++) {
              ConverterMain.options.getsave(0).listofidsinsave[ntype] =
                  (List<Object>) ois.readObject();
              ConverterMain.options.getsave(0).nidsinsave[ntype] =
                  (TreeMap<Object, Integer>) ois.readObject();
            }
            ois.close();
            ConverterMain.isdone.put("analyzesave", true);
            Logger.logln("Finished reading the cached analyze map for the origin save");
            // Print();
            return;
          } catch (IOException e) {
            Logger.logln("Couldn't read the ID map  cache");
          } catch (ClassNotFoundException e) {
            Logger.logln("Couldn't read the ID map  cache");
          }
        }
      }

      FilenameFilter directoryFilter =
          new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
              File file = new File(dir, name);
              return file.isDirectory();
            }
          };

      class FileWalker {
        TreeSet<File> regionfiles = new TreeSet<File>();

        public void walk(File root) {
          File[] list = root.listFiles();

          for (File f : list) {
            if (f.isDirectory()) {
              walk(f);
            } else {
              if (f.getName().endsWith(".mca")) {
                regionfiles.add(root);
              }
            }
          }
        }
      }

      for (int ntype = 0; ntype < ConverterMain.Ntype; ntype++) {
        problematicids[ntype] = new ArrayList<Object>();
        removedids[ntype] = new ArrayList<Object>();
        converteds[ntype] = new ArrayList<Object>();
        nconverteds[ntype] = new TreeMap<Object, Integer>();
        ConverterMain.options.getsave(0).listofidsinsave[ntype] = new ArrayList<Object>();
        ConverterMain.options.getsave(0).nidsinsave[ntype] = new TreeMap<Object, Integer>();
      }

      FileWalker filewalker0 = new FileWalker();
      filewalker0.walk(rootfolderorig);
      List<Object> list = Arrays.asList(filewalker0.regionfiles.toArray());
      Collections.shuffle(list);
      Iterator it = list.iterator();

      // for (int nr=0;nr<regions.length;nr++){
      while (it.hasNext()) {
        File oldregionfolder = (File) it.next();

        String relative = rootfolderorig.toURI().relativize(oldregionfolder.toURI()).getPath();

        File newregionfolder = new File(rootfolderdest, relative);
        if (!oldregionfolder.exists() || !oldregionfolder.isDirectory()) {
          Logger.logln("ERROR with the regions directory");
          return;
        }

        File[] regionfiles = newregionfolder.listFiles();
        if (convert) {
          Logger.logln(
              "Converting " + relative + " files from " + oldregionfolder.getCanonicalPath());
          Logger.logln("                          to " + newregionfolder.getCanonicalPath());
        } else {
          Logger.logln(
              "Analyzing " + relative + " files from " + oldregionfolder.getCanonicalPath());
        }
        for (int nf = 0; nf < regionfiles.length; nf++) {
          currentregionname = regionfiles[nf].getName();
          RegionFile newregion = new RegionFile(regionfiles[nf]);
          RegionFile oldregion =
              new RegionFile(new File(oldregionfolder, regionfiles[nf].getName()));
          Logger.logln(
              "Treating "
                  + relative
                  + " file "
                  + (nf + 1)
                  + "/"
                  + regionfiles.length
                  + "   "
                  + currentregionname);
          MainFrame.updateframe();
          int blabla = 1;
          for (xc = 0; xc < 32; xc++) {
            for (zc = 0; zc < 32; zc++) {
              if (stop) {
                return;
              }
              if (oldregion.hasChunk(xc, zc)) {
                // System.out.println(xc+" "+zc);
                try {
                  DataInputStream dis = oldregion.getChunkDataInputStream(xc, zc);
                  DataOutputStream dos = newregion.getChunkDataOutputStream(xc, zc);
                  CompoundTag comptag = NbtIo.read(dis);
                  dis.close();
                  CompoundTag comptag2 = (CompoundTag) comptag.copy();
                  CompoundTag leveldata = comptag2.getCompound("Level");

                  heightmap = leveldata.getIntArray("HeightMap");

                  currentmode = "Blocks";
                  ListTag sectionsdata = leveldata.getList("Sections");
                  for (int ns = 0; ns < sectionsdata.size(); ns++) {
                    // CompoundTag tag=;
                    treatblocks((CompoundTag) sectionsdata.get(ns), convert);
                    // tag.putByteArray("Blocks", convertblocks(tag.getByteArray("Blocks")));
                    // tag.putByteArray("Add", convertblocksAdd(tag.getByteArray("Add")));
                  }
                  // long t0=System.currentTimeMillis();

                  currentmode = "Entities_Items";
                  traverseTags_treatitems(leveldata.getList("Entities"), convert);

                  currentmode = "Entities";
                  treatentities(leveldata.getList("Entities"), 2, convert);

                  //									currentmode="TileEntities";
                  //									treatentities(leveldata.getList("TileEntities"),3,convert);

                  currentmode = "TileEntities_Items";
                  traverseTags_treatitems(leveldata.getList("TileEntities"), convert);

                  // long t1=System.currentTimeMillis();
                  // System.out.println(" "+(t1-t0));

                  if (convert) {
                    NbtIo.write(comptag2, dos);
                    dos.flush();
                    dos.close();
                  }
                  //									dis=oldregion.getChunkDataInputStream(xc,zc);
                  //									CompoundTag comptag3=NbtIo.read(dis);
                  //									System.out.println(comptag3.equals(comptag));

                } catch (IOException e) {
                  Logger.logln("Unrecoverable Problem reading chunk data. Possibly corrupt level");
                }
              }
            }
          }
        }
      }

      for (int ntype = 0; ntype < ConverterMain.Ntype; ntype++) {
        Iterator it2 = nconverteds[ntype].keySet().iterator();
        while (it2.hasNext()) {
          Integer id = (Integer) it2.next();
          if (nconverteds[ntype].get(id) > 0) {
            Logger.logln(
                "Converted "
                    + nconverteds[ntype].get(id)
                    + "("
                    + ConverterMain.idmaps[ntype].get(0).get(id)
                    + ") "
                    + ConverterMain.typenames[ntype]
                    + " with ID :"
                    + id
                    + " to "
                    + ConverterMain.options.getconvertmaps()[ntype].get(id)
                    + "("
                    + ConverterMain.idmaps[ntype].get(1).get(id)
                    + ")");
          }
        }
      }
      if (!convert) {
        Logger.logln("Finished the analysis.");
        FileOutputStream fos = new FileOutputStream(cachefile);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        for (int ntype = 0; ntype < ConverterMain.Ntype; ntype++) {
          oos.writeObject(ConverterMain.options.getsave(0).listofidsinsave[ntype]);
          oos.writeObject(ConverterMain.options.getsave(0).nidsinsave[ntype]);
        }
        oos.close();
        // Print();
      } else {
        Logger.logln("Finished the conversion ! Hopefully.");
      }
      for (int ntype = 0; ntype < ConverterMain.Ntype; ntype++) {
        problematicids[ntype].clear();
        converteds[ntype].clear();
        nconverteds[ntype].clear();
      }
      ConverterMain.options.save();

    } catch (IOException e) {
      Logger.logln("ERROR accessing the save folder");
      return;
    }
    return;
  }