public void enablePlugin(final Plugin plugin) {
    if (!(plugin instanceof JavaPlugin)) {
      throw new IllegalArgumentException("Plugin is not associated with this PluginLoader");
    }

    if (!plugin.isEnabled()) {
      JavaPlugin jPlugin = (JavaPlugin) plugin;

      String pluginName = jPlugin.getDescription().getName();

      if (!loaders.containsKey(pluginName)) {
        loaders.put(pluginName, (PluginClassLoader) jPlugin.getClassLoader());
      }

      try {
        jPlugin.setEnabled(true);
      } catch (Throwable ex) {
        server
            .getLogger()
            .log(
                Level.SEVERE,
                "Error occurred while enabling "
                    + plugin.getDescription().getFullName()
                    + " (Is it up to date?): "
                    + ex.getMessage(),
                ex);
      }

      // Perhaps abort here, rather than continue going, but as it stands,
      // an abort is not possible the way it's currently written
      server.getPluginManager().callEvent(new PluginEnableEvent(plugin));
    }
  }
  public void disablePlugin(Plugin plugin) {
    if (!(plugin instanceof JavaPlugin)) {
      throw new IllegalArgumentException("Plugin is not associated with this PluginLoader");
    }

    if (plugin.isEnabled()) {
      JavaPlugin jPlugin = (JavaPlugin) plugin;
      ClassLoader cloader = jPlugin.getClassLoader();

      try {
        jPlugin.setEnabled(false);
      } catch (Throwable ex) {
        server
            .getLogger()
            .log(
                Level.SEVERE,
                "Error occurred while disabling "
                    + plugin.getDescription().getFullName()
                    + " (Is it up to date?): "
                    + ex.getMessage(),
                ex);
      }

      server.getPluginManager().callEvent(new PluginDisableEvent(plugin));

      loaders.remove(jPlugin.getDescription().getName());

      if (cloader instanceof PluginClassLoader) {
        PluginClassLoader loader = (PluginClassLoader) cloader;
        Set<String> names = loader.getClasses();

        for (String name : names) {
          removeClass(name);
        }
      }
    }
  }
  public Plugin loadPlugin(File file, boolean ignoreSoftDependencies)
      throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
    JavaPlugin result = null;
    PluginDescriptionFile description = null;

    if (!file.exists()) {
      throw new InvalidPluginException(
          new FileNotFoundException(String.format("%s does not exist", file.getPath())));
    }
    try {
      JarFile jar = new JarFile(file);
      JarEntry entry = jar.getJarEntry("plugin.yml");

      if (entry == null) {
        throw new InvalidPluginException(
            new FileNotFoundException("Jar does not contain plugin.yml"));
      }

      InputStream stream = jar.getInputStream(entry);

      description = new PluginDescriptionFile(stream);

      stream.close();
      jar.close();
    } catch (IOException ex) {
      throw new InvalidPluginException(ex);
    } catch (YAMLException ex) {
      throw new InvalidPluginException(ex);
    }

    File dataFolder = new File(file.getParentFile(), description.getName());
    File oldDataFolder = getDataFolder(file);

    // Found old data folder
    if (dataFolder.equals(oldDataFolder)) {
      // They are equal -- nothing needs to be done!
    } else if (dataFolder.isDirectory() && oldDataFolder.isDirectory()) {
      server
          .getLogger()
          .log(
              Level.INFO,
              String.format(
                  "While loading %s (%s) found old-data folder: %s next to the new one: %s",
                  description.getName(), file, oldDataFolder, dataFolder));
    } else if (oldDataFolder.isDirectory() && !dataFolder.exists()) {
      if (!oldDataFolder.renameTo(dataFolder)) {
        throw new InvalidPluginException(
            new Exception(
                "Unable to rename old data folder: '"
                    + oldDataFolder
                    + "' to: '"
                    + dataFolder
                    + "'"));
      }
      server
          .getLogger()
          .log(
              Level.INFO,
              String.format(
                  "While loading %s (%s) renamed data folder: '%s' to '%s'",
                  description.getName(), file, oldDataFolder, dataFolder));
    }

    if (dataFolder.exists() && !dataFolder.isDirectory()) {
      throw new InvalidPluginException(
          new Exception(
              String.format(
                  "Projected datafolder: '%s' for %s (%s) exists and is not a directory",
                  dataFolder, description.getName(), file)));
    }

    ArrayList<String> depend;

    try {
      depend = (ArrayList) description.getDepend();
      if (depend == null) {
        depend = new ArrayList<String>();
      }
    } catch (ClassCastException ex) {
      throw new InvalidPluginException(ex);
    }

    for (String pluginName : depend) {
      if (loaders == null) {
        throw new UnknownDependencyException(pluginName);
      }
      PluginClassLoader current = loaders.get(pluginName);

      if (current == null) {
        throw new UnknownDependencyException(pluginName);
      }
    }

    if (!ignoreSoftDependencies) {
      ArrayList<String> softDepend;

      try {
        softDepend = (ArrayList) description.getSoftDepend();
        if (softDepend == null) {
          softDepend = new ArrayList<String>();
        }
      } catch (ClassCastException ex) {
        throw new InvalidPluginException(ex);
      }

      for (String pluginName : softDepend) {
        if (loaders == null) {
          throw new UnknownSoftDependencyException(pluginName);
        }
        PluginClassLoader current = loaders.get(pluginName);

        if (current == null) {
          throw new UnknownSoftDependencyException(pluginName);
        }
      }
    }

    PluginClassLoader loader = null;

    try {
      URL[] urls = new URL[1];

      urls[0] = file.toURI().toURL();
      loader = new PluginClassLoader(this, urls, getClass().getClassLoader());
      Class<?> jarClass = Class.forName(description.getMain(), true, loader);
      Class<? extends JavaPlugin> plugin = jarClass.asSubclass(JavaPlugin.class);

      Constructor<? extends JavaPlugin> constructor = plugin.getConstructor();

      result = constructor.newInstance();

      result.initialize(this, server, description, dataFolder, file, loader);
    } catch (Throwable ex) {
      throw new InvalidPluginException(ex);
    }

    loaders.put(description.getName(), loader);

    return result;
  }