docs: public static ManifestInfo parseManifest(JarFile jar) throws RepositoryArchiveException, RepositoryArchiveIOException {
  
          String prov = null;
  
          // Create the WLPInformation and populate it
          Manifest mf = null;
          try {
              mf = jar.getManifest();
          } catch (IOException e) {
              throw new RepositoryArchiveIOException("Unable to access manifest in sample", new File(jar.getName()), e);
          } finally {
              try {
                  jar.close();
              } catch (IOException e) {
                  throw new RepositoryArchiveIOException("Unable to access manifest in sample", new File(jar.getName()), e);
              }
          }
  
          if (null == mf) {
              throw new RepositoryArchiveEntryNotFoundException("No manifest file found in sample", new File(jar.getName()), "/META-INF/MANIFEST.MF");
          }
  
          String appliesTo = null;
          ResourceType type = null;
          List<String> requiresList = new ArrayList<String>();
  
          Attributes mainattrs = mf.getMainAttributes();
  
          // Iterate over the main attributes in the manifest and look for the ones we are interested in.
          for (Object at : mainattrs.keySet()) {
              String attribName = ((Attributes.Name) at).toString();
              String attribValue = (String) mainattrs.get(at);
  
              if (APPLIES_TO.equals(attribName)) {
                  appliesTo = attribValue;
              } else if (SAMPLE_TYPE.equals(attribName)) {
                  String typeString = (String) mainattrs.get(at);
                  if (SAMPLE_TYPE_OPENSOURCE.equals(typeString)) {
                      type = ResourceType.OPENSOURCE;
                  } else if (SAMPLE_TYPE_PRODUCT.equals(typeString)) {
                      type = ResourceType.PRODUCTSAMPLE;
                  } else {
                      throw new IllegalArgumentException("The following jar file is not a known sample type " + jar.getName());
                  }
              } else if (REQUIRE_FEATURE.equals(attribName)) {
  
                  // We need to split the required features, from a String of comma seperated
                  // features into a List of String, where each String is a feature name.
                  StringTokenizer featuresTokenizer = new StringTokenizer(attribValue, ",");
                  while (featuresTokenizer.hasMoreElements()) {
                      String nextFeature = (String) featuresTokenizer.nextElement();
                      requiresList.add(nextFeature);
                  }
              } else if (PROVIDER.equals(attribName)) {
                  prov = attribValue;
              }
          }
  
          if (null == prov) {
              throw new RepositoryArchiveInvalidEntryException("No Bundle-Vendor specified in the sample's manifest", new File(jar.getName()), "/META-INF/MANIFEST.MF");
          }
          if (null == type) {
              throw new RepositoryArchiveInvalidEntryException("No Sample-Type specified in the sample's manifest", new File(jar.getName()), "/META-INF/MANIFEST.MF");
          }
  
          String archiveRoot = mainattrs.getValue("Archive-Root");
          archiveRoot = archiveRoot != null ? archiveRoot : "";
  
          ManifestInfo mi = new ManifestInfo(prov, appliesTo, type, requiresList, archiveRoot, mf);
  
          return mi;
      }