private void checkDependencies(
     Iterable<PluginMetadata.Dependency> dependencies, Messager messager) {
   for (PluginMetadata.Dependency dependency : dependencies) {
     final String version = dependency.getVersion();
     if (version != null) {
       try {
         VersionRange.createFromVersionSpec(version);
       } catch (InvalidVersionSpecificationException e) {
         messager.printMessage(
             ERROR,
             "Invalid dependency version range from extra metadata file: "
                 + version
                 + " ("
                 + e.getMessage()
                 + ") Please check the Javadocs of @Dependency.version() for details.",
             this.element,
             this.annotation.getMirror());
       }
     }
   }
 }
  void apply(Messager messager) {
    String value = this.annotation.get().id();
    if (!ID_PATTERN.matcher(value).matches()) {
      messager.printMessage(
          ERROR,
          "Plugin ID '" + value + "' should match pattern " + ID_PATTERN.pattern(),
          this.element,
          this.annotation.getMirror(),
          this.annotation.getValue("id"));
    }

    if (value.indexOf('.') == -1) {
      messager.printMessage(
          WARNING,
          "Unqualified plugin ID '"
              + value
              + "'. It is recommend to prefix your plugin ID with a qualified group. "
              + "See the @Plugin Javadocs for details.",
          this.element,
          this.annotation.getMirror(),
          this.annotation.getValue("id"));
    }

    value = this.annotation.get().name();
    if (value.isEmpty()) {
      if (this.metadata.getName() == null) {
        messager.printMessage(
            WARNING, "Missing plugin name", this.element, this.annotation.getMirror());
      }
    } else {
      this.metadata.setName(value);
    }

    value = this.annotation.get().version();
    if (value.isEmpty()) {
      if (this.metadata.getVersion() == null) {
        messager.printMessage(
            WARNING, "Missing plugin version", this.element, this.annotation.getMirror());
      }
    } else {
      this.metadata.setVersion(value);
    }

    value = this.annotation.get().description();
    if (value.isEmpty()) {
      if (this.metadata.getDescription() == null) {
        messager.printMessage(
            WARNING, "Missing plugin description", this.element, this.annotation.getMirror());
      }
    } else {
      this.metadata.setDescription(value);
    }

    value = this.annotation.get().url();
    if (!value.isEmpty()) {
      if (!isLikelyValidUrl(value)) {
        messager.printMessage(
            ERROR,
            "Invalid URL: " + value,
            this.element,
            this.annotation.getMirror(),
            this.annotation.getValue("url"));
      }

      this.metadata.setUrl(value);
    } else if ((value = this.metadata.getUrl()) != null) {
      if (!isLikelyValidUrl(value)) {
        messager.printMessage(
            ERROR,
            "Invalid URL: " + value + " in extra metadata files",
            this.element,
            this.annotation.getMirror());
      }
    }

    value = this.annotation.get().assets();
    if (!value.isEmpty()) {
      if (!isValidPath(value)) {
        messager.printMessage(
            ERROR,
            "Invalid asset directory path: " + value,
            this.element,
            this.annotation.getMirror(),
            this.annotation.getValue("assets"));
      }
      SpongeExtension ext = new SpongeExtension();
      ext.setAssetDirectory(value);
      this.metadata.setExtension("sponge", ext);
    } else {
      SpongeExtension ext = this.metadata.getExtension("sponge");
      if (ext != null && ext.getAssetDirectory() != null && !isValidPath(ext.getAssetDirectory())) {
        messager.printMessage(
            ERROR,
            "Invalid asset directory path: " + value + " in extra metadata files",
            this.element,
            this.annotation.getMirror());
      }
    }

    String[] authors = this.annotation.get().authors();
    if (authors.length > 0) {
      this.metadata.getAuthors().clear();
      for (String author : authors) {
        if (author.isEmpty()) {
          messager.printMessage(
              ERROR,
              "Empty author is not allowed",
              this.element,
              this.annotation.getMirror(),
              this.annotation.getValue("authors"));
          continue;
        }

        this.metadata.addAuthor(author);
      }
    }

    checkDependencies(this.metadata.getRequiredDependencies(), messager);
    checkDependencies(this.metadata.getLoadAfter(), messager);
    checkDependencies(this.metadata.getLoadBefore(), messager);

    Dependency[] dependencies = this.annotation.get().dependencies();
    if (dependencies.length > 0) {
      for (Dependency dependency : dependencies) {
        final String id = dependency.id();
        if (id.isEmpty()) {
          messager.printMessage(
              ERROR,
              "Dependency ID should not be empty",
              this.element,
              this.annotation.getMirror(),
              this.annotation.getValue("dependencies"));
        }

        final String version = dependency.version();
        if (!version.isEmpty()) {
          try {
            VersionRange.createFromVersionSpec(version);
          } catch (InvalidVersionSpecificationException e) {
            messager.printMessage(
                ERROR,
                "Invalid dependency version range: "
                    + version
                    + " ("
                    + e.getMessage()
                    + ") Please check the Javadocs of @Dependency.version() for details.",
                this.element,
                this.annotation.getMirror(),
                this.annotation.getValue("dependencies"));
          }
        }

        // TODO: Load order
        this.metadata.loadAfter(
            new PluginMetadata.Dependency(id, dependency.version()), !dependency.optional());
      }
    }
  }