/**
   * All the BND magic happens here.
   *
   * @param jarInputStream On what to operate.
   * @param instructions BND instructions from user API
   * @param symbolicName Mandatory Header. In case user does not set it.
   * @return Bundle Jar Stream
   * @throws Exception Problems go here
   */
  private InputStream createBundle(
      InputStream jarInputStream, Properties instructions, String symbolicName) throws Exception {
    NullArgumentException.validateNotNull(jarInputStream, "Jar URL");
    NullArgumentException.validateNotNull(instructions, "Instructions");
    NullArgumentException.validateNotEmpty(symbolicName, "Jar info");

    final Jar jar = new Jar("dot", sink(jarInputStream));

    final Properties properties = new Properties();
    properties.putAll(instructions);

    final Analyzer analyzer = new Analyzer();
    analyzer.setJar(jar);
    analyzer.setProperties(properties);

    // throw away already existing headers that we overwrite:

    analyzer.mergeManifest(jar.getManifest());

    checkMandatoryProperties(analyzer, jar, symbolicName);
    Manifest manifest = analyzer.calcManifest();
    jar.setManifest(manifest);

    return createInputStream(jar);
  }
  private Manifest _calculateManifest(URL url, Manifest manifest) {
    Analyzer analyzer = new Analyzer();

    Jar jar = null;

    try {
      URLConnection urlConnection = url.openConnection();

      String fileName = url.getFile();

      if (urlConnection instanceof JarURLConnection) {
        JarURLConnection jarURLConnection = (JarURLConnection) urlConnection;

        URL jarFileURL = jarURLConnection.getJarFileURL();

        fileName = jarFileURL.getFile();
      }

      File file = new File(fileName);

      if (!file.exists() || !file.canRead()) {
        return manifest;
      }

      fileName = file.getName();

      analyzer.setJar(new Jar(fileName, file));

      jar = analyzer.getJar();

      String bundleSymbolicName = fileName;

      Matcher matcher = _bundleSymbolicNamePattern.matcher(bundleSymbolicName);

      if (matcher.matches()) {
        bundleSymbolicName = matcher.group(1);
      }

      analyzer.setProperty(Analyzer.BUNDLE_SYMBOLICNAME, bundleSymbolicName);

      String exportPackage = _calculateExportPackage(jar);

      analyzer.setProperty(Analyzer.EXPORT_PACKAGE, exportPackage);

      analyzer.mergeManifest(manifest);

      String bundleVersion = analyzer.getProperty(Analyzer.BUNDLE_VERSION);

      if (bundleVersion != null) {
        bundleVersion = Builder.cleanupVersion(bundleVersion);

        analyzer.setProperty(Analyzer.BUNDLE_VERSION, bundleVersion);
      }

      return analyzer.calcManifest();
    } catch (Exception e) {
      _log.error(e, e);

      return manifest;
    } finally {
      if (jar != null) {
        jar.close();
      }

      analyzer.close();
    }
  }