public void unloadAndDelete(SmallModuleEntry sme) {
    UploaderPlugin up;
    synchronized (this) {
      up = sme.up;
      sme.up = null; // deactivate initiated here
      if (up == null) {
        Path zipPath = UploaderPlugin.getLocalPath(updateLocation, sme);
        if (Files.exists(zipPath)) {
          try {
            Files.delete(zipPath);
          } catch (Exception a) {
            System.out.println("could not delete unactive plugin " + sme.getName());
          }
        }
        return;
      }
    }

    try {
      up.destroy();
    } catch (Exception a) {
      System.out.println("could not destory plugin " + sme.getName());
      a.printStackTrace();
    }
  }
  public void initIndex() throws Exception {
    try {
      Files.createDirectories(updateLocation);
    } catch (Exception a) {
      // ignore
    }
    long startUpdate = System.currentTimeMillis();
    System.out.println("fetching updates ");
    updateIndex();
    long span = System.currentTimeMillis() - startUpdate;
    System.out.println("done updates index - time taken = " + span);
    i = new Index(updateLocation.resolve("index.json"));

    LinkedList<Runnable> updateOperations = new LinkedList<>();
    for (SmallModuleEntry sme : i.getSmallModuleEntrys()) {
      LocallyPresent locallyPresent = UploaderPlugin.locallyPresent(updateLocation, sme);
      if (locallyPresent != LocallyPresent.ABSENT) {
        if (sme.isDead()) {
          deleteLocal(sme); // dead plugins get cleaned. :D
        } else {
          updateOperations.add(loadInNewThread(sme));
        }
      }
    }
    ReactiveThread rt =
        ReactiveThread.create(
            CompletionCallback.DUMMY,
            "Updating all plugins",
            updateOperations.toArray(new Runnable[updateOperations.size()]));
    rt.setDaemon(true);
    rt.start();
  }
  private UploaderPlugin load(SmallModuleEntry sme, int cnt) {
    synchronized (sme) {
      if (sme.up != null) {
        if (!sme.up.intitalized()) {
          ReactiveThread rt = sme.up.rt;
          if (rt == null) {
            if (cnt > 3) return sme.up;
            return load(sme, cnt + 1);
          }
          try {
            waitTill(rt, 3000, 100, 1d);
          } catch (InterruptedException ex) {
          }
        }
        return sme.up;
      }

      UploaderPlugin up = new UploaderPlugin(sme, updateLocation);

      sme.up = up;
    }
    final Content c = upui.addContent(sme.getName());
    try {
      sme.up.create(c);
    } catch (Exception a) {
      System.out.println("for plugin " + sme.getName());
      a.printStackTrace();
      c.done();
      return null;
      // if this happens, the check box should get unchecked
      // map.remove(entry.getKey()); //<< this is not going to work
    }
    return load(sme, cnt + 1);
  }