private List<LazyHostPlugin> update(
      LogSource logger,
      final List<LazyHostPlugin> updateCache,
      final AtomicLong lastFolderModification)
      throws Exception {
    final List<LazyHostPlugin> retList = new ArrayList<LazyHostPlugin>();
    for (PluginInfo<PluginForHost> pluginInfo :
        scan(logger, "jd/plugins/hoster", updateCache, lastFolderModification)) {

      if (pluginInfo.getLazyPlugin() != null) {
        final LazyHostPlugin plugin = (LazyHostPlugin) pluginInfo.getLazyPlugin();
        retList.add(plugin);
        // logger.finer("@HostPlugin ok(cached):" + plugin.getClassName() + " " +
        // plugin.getDisplayName() + " " +
        // plugin.getVersion());
      } else {
        final String simpleName = new String(pluginInfo.getClazz().getSimpleName());
        final HostPlugin a = pluginInfo.getClazz().getAnnotation(HostPlugin.class);
        if (a != null) {
          try {
            final long revision = pluginInfo.getLazyPluginClass().getRevision();
            String[] names = a.names();
            String[] patterns = a.urls();
            int[] flags = a.flags();
            if (names.length == 0) {
              /* create multiple hoster plugins from one source */
              patterns =
                  (String[])
                      pluginInfo
                          .getClazz()
                          .getDeclaredMethod("getAnnotationUrls", new Class[] {})
                          .invoke(null, new Object[] {});
              names =
                  (String[])
                      pluginInfo
                          .getClazz()
                          .getDeclaredMethod("getAnnotationNames", new Class[] {})
                          .invoke(null, new Object[] {});
              flags =
                  (int[])
                      pluginInfo
                          .getClazz()
                          .getDeclaredMethod("getAnnotationFlags", new Class[] {})
                          .invoke(null, new Object[] {});
            }
            if (patterns.length != names.length) {
              //
              throw new WTFException("names.length != patterns.length");
            }
            if (flags.length != names.length && a.interfaceVersion() == 2) {
              /* interfaceVersion 2 is for Stable/Nightly */
              logger.log(
                  (new WTFException(
                      "PLUGIN STABLE ISSUE!! names.length("
                          + names.length
                          + ")!= flags.length("
                          + flags.length
                          + ")->"
                          + simpleName)));
            }
            if (names.length == 0) {
              //
              throw new WTFException("names.length=0");
            }
            final PluginClassLoaderChild classLoader =
                (PluginClassLoaderChild) pluginInfo.getClazz().getClassLoader();
            /* during init we dont want dummy libs being created */
            classLoader.setCreateDummyLibs(false);
            for (int i = 0; i < names.length; i++) {
              LazyHostPlugin lazyHostPlugin = null;
              try {
                lazyHostPlugin =
                    new LazyHostPlugin(
                        pluginInfo.getLazyPluginClass(),
                        new String(patterns[i]),
                        new String(names[i]),
                        pluginInfo.getClazz(),
                        classLoader);
                if (list != null) {
                  final LazyHostPlugin previousLazyHostPlugin =
                      list.get(lazyHostPlugin.getDisplayName());
                  if (previousLazyHostPlugin != null) {
                    lazyHostPlugin.setPluginUsage(previousLazyHostPlugin.getPluginUsage());
                  }
                }
                try {
                  /* check for stable compatibility */
                  classLoader.setPluginClass(pluginInfo.getClazz().getName());
                  classLoader.setCheckStableCompatibility(
                      pluginInfo.getLazyPluginClass().getInterfaceVersion() == 2);
                  final PluginForHost plg = lazyHostPlugin.newInstance(classLoader);
                  /* set configinterface */
                  final Class<? extends ConfigInterface> configInterface = plg.getConfigInterface();
                  if (configInterface != null) {
                    lazyHostPlugin.setConfigInterface(new String(configInterface.getName()));
                  } else {
                    lazyHostPlugin.setConfigInterface(null);
                  }
                  /* set premium */
                  if (plg.isPremiumEnabled()) {
                    lazyHostPlugin.setPremium(true);
                    /* set premiumUrl */
                    final String purl = plg.getBuyPremiumUrl();
                    if (purl != null) {
                      lazyHostPlugin.setPremiumUrl(new String(purl));
                    }
                  } else {
                    lazyHostPlugin.setPremium(false);
                  }
                  /* set hasConfig */
                  lazyHostPlugin.setHasConfig(plg.hasConfig());

                  try {
                    lazyHostPlugin.setHasAllowHandle(PluginForHost.implementsAllowHandle(plg));
                  } catch (Throwable e) {
                    logger.log(e);
                    lazyHostPlugin.setHasAllowHandle(false);
                  }

                  try {
                    lazyHostPlugin.setHasRewrite(PluginForHost.implementsRewriteHost(plg));
                  } catch (Throwable e) {
                    logger.log(e);
                    lazyHostPlugin.setHasRewrite(false);
                  }

                } catch (Throwable e) {
                  if (e instanceof UpdateRequiredClassNotFoundException) {
                    logger.log(e);
                    logger.finest(
                        "@HostPlugin incomplete:"
                            + simpleName
                            + " "
                            + new String(names[i])
                            + " "
                            + e.getMessage()
                            + " "
                            + revision);
                  } else {
                    throw e;
                  }
                }
                if (lazyHostPlugin != null) {
                  retList.add(lazyHostPlugin);
                  // logger.finer("@HostPlugin ok:" + simpleName + " " + new String(names[i]) + " "
                  // + revision);
                }
              } catch (Throwable e) {
                logger.log(e);
                logger.severe(
                    "@HostPlugin failed:"
                        + simpleName
                        + " "
                        + new String(names[i])
                        + " "
                        + revision);
              } finally {
                /* now the pluginClassLoad may create dummy libraries */
                if (lazyHostPlugin != null) {
                  lazyHostPlugin.setClassLoader(null);
                  lazyHostPlugin.setPluginClass(null);
                }
              }
            }
          } catch (final Throwable e) {
            logger.severe("@HostPlugin failed:" + simpleName);
            logger.log(e);
          }
        } else {
          logger.severe("@HostPlugin missing:" + simpleName);
        }
      }
    }
    return retList;
  }
 @Override
 protected long[] getInfos(Class<PluginForHost> clazz) {
   final HostPlugin infos = clazz.getAnnotation(HostPlugin.class);
   return new long[] {infos.interfaceVersion(), Formatter.getRevision(infos.revision())};
 }