@Override
  public void generate(final GenerationContext context) throws Exception {
    final String id = getString(context.getArtifactInformation().getMetaData(), ID, "id");
    final String version = getString(context.getArtifactInformation().getMetaData(), ID, "version");

    final Path tmp = Files.createTempFile("p2-feat-", ".jar");

    try {
      try (final ZipOutputStream jar = new ZipOutputStream(new FileOutputStream(tmp.toFile()))) {
        final ZipEntry ze = new ZipEntry("feature.xml");
        jar.putNextEntry(ze);
        createFeatureXml(jar, context.getArtifactInformation().getMetaData(), context);
      }

      final Map<MetaKey, String> providedMetaData = new HashMap<>();
      try (BufferedInputStream is = new BufferedInputStream(new FileInputStream(tmp.toFile()))) {
        context.createVirtualArtifact(
            String.format("%s-%s.jar", id, version), is, providedMetaData);
      }
    } finally {
      Files.deleteIfExists(tmp);
    }
  }
  private void createFeatureXml(
      final OutputStream out, final Map<MetaKey, String> map, final GenerationContext context)
      throws Exception {
    final String id = getString(map, ID, "id");
    final String version = makeVersion(getString(map, ID, "version"));
    final String label = getString(map, ID, "label");

    final String description = getString(map, ID, "description");
    final String copyright = getString(map, ID, "copyright");
    final String license = getString(map, ID, "license");

    final String descriptionUrl = getString(map, ID, "descriptionUrl");
    final String copyrightUrl = getString(map, ID, "copyrightUrl");
    final String licenseUrl = getString(map, ID, "licenseUrl");

    final String provider = getString(map, ID, "provider");

    final Document doc = this.xml.create();
    final Element root = doc.createElement("feature");
    doc.appendChild(root);

    root.setAttribute("id", id);
    root.setAttribute("version", version);
    root.setAttribute("label", label);

    if (provider != null) {
      root.setAttribute("provider-name", provider);
    }

    createLegalEntry(root, "description", description, descriptionUrl);
    createLegalEntry(root, "copyright", copyright, copyrightUrl);
    createLegalEntry(root, "license", license, licenseUrl);

    for (final ArtifactInformation a : context.getChannelArtifacts()) {
      processPlugin(root, a);
    }

    this.xml.write(doc, out);
  }
  @Override
  public void generate(final GenerationContext context) throws Exception {
    Document doc;
    try (BufferedInputStream is =
        new BufferedInputStream(Files.newInputStream(context.getFile()))) {
      doc = this.xml.parse(is);
    }

    final CategoryDefinition def = CategoryXmlParser.parse(doc);

    final String baseName = context.getArtifactInformation().getName();

    final Map<String, Set<ArtifactInformation>> map = new HashMap<>();

    for (final ArtifactInformation ai : context.getChannelArtifacts()) {
      if (Helper.isBundle(ai.getMetaData())) {
        final String id = ai.getMetaData().get(MK_OSGI_NAME);
        final Set<String> cats = def.getBundles().get(id);
        if (cats != null) {
          for (final String cat : cats) {
            addMap(map, cat, ai);
          }
        }
      }

      if (Helper.isFeature(ai.getMetaData())) {
        final String id = ai.getMetaData().get(MK_OSGI_NAME);
        final Set<String> cats = def.getFeatures().get(id);
        if (cats != null) {
          for (final String cat : cats) {
            addMap(map, cat, ai);
          }
        }
      }
    }

    context.createVirtualArtifact(
        baseName + "-p2metadata.xml",
        out -> {
          Helper.createFragmentFile(
              out,
              (units) -> {
                for (final Category cat : def.getCategories()) {
                  Helper.createCategoryUnit(
                      units,
                      cat.getId(),
                      cat.getLabel(),
                      cat.getDescription(),
                      Helper.makeDefaultVersion(),
                      (unit) -> {
                        final Element reqs = XmlHelper.addElement(unit, "requires");

                        final Set<String> ctx = new HashSet<>();

                        final Set<ArtifactInformation> list = map.get(cat.getId());
                        if (list != null) {
                          for (final ArtifactInformation ai : list) {
                            if (Helper.isFeature(ai.getMetaData())) {
                              Helper.addFeatureRequirement(ctx, reqs, ai);
                            } else if (Helper.isBundle(ai.getMetaData())) {
                              Helper.addBundleRequirement(ctx, reqs, ai);
                            }
                          }
                        }
                        XmlHelper.fixSize(reqs);
                      });
                }
              });
        },
        null);
  }