/**
   * Crate a plug-in project with the given name
   *
   * @param projectName
   * @param additionalNatures
   * @return a new plug-in project
   * @throws CoreException
   */
  public static IJavaProject createPluginProject(String projectName, String[] additionalNatures)
      throws CoreException {
    String[] resolvednatures = additionalNatures;
    if (additionalNatures != null) {
      ArrayList<String> natures = new ArrayList<String>(Arrays.asList(additionalNatures));
      if (!natures.contains(IBundleProjectDescription.PLUGIN_NATURE)) {
        // need to always set this one first, in case others depend on it, like API Tools does
        natures.add(0, IBundleProjectDescription.PLUGIN_NATURE);
      }
      if (!natures.contains(JavaCore.NATURE_ID)) {
        natures.add(0, JavaCore.NATURE_ID);
      }
      resolvednatures = (String[]) natures.toArray(new String[natures.size()]);
    }

    IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
    IBundleProjectService service = getBundleProjectService();
    IBundleProjectDescription description = service.getDescription(project);
    IBundleClasspathEntry entry =
        service.newBundleClasspathEntry(new Path(SRC_FOLDER), new Path(BIN_FOLDER), null);
    description.setSymbolicName(projectName);
    description.setBundleClasspath(new IBundleClasspathEntry[] {entry});
    description.setNatureIds(resolvednatures);
    description.setBundleVendor("ibm");
    description.setTargetVersion(IBundleProjectDescription.VERSION_3_4);
    description.setExtensionRegistry(true);
    description.setEquinox(true);
    description.setBundleVersion(new Version("1.0.0"));
    description.setExecutionEnvironments(new String[] {"J2SE-1.5"});
    description.apply(null);
    AbstractApiTest.waitForAutoBuild();
    return JavaCore.create(project);
  }
  /**
   * Tests that an exported package removal in the PDE model is reflected in the workspace api
   * baseline
   */
  public void testWPUpdateExportPackageRemoved() throws Exception {
    IJavaProject project = getTestingProject();
    assertNotNull("The testing project must exist", project);

    // add package
    assertTestPackage(
        project,
        new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute(),
        "export1");

    setPackageToApi(project, "export1");
    IApiAnnotations annot =
        getTestProjectApiDescription().resolveAnnotations(Factory.packageDescriptor("export1"));
    assertNotNull("there must be an annotation for the new exported package", annot);
    assertTrue(
        "the newly exported package must be API visibility",
        annot.getVisibility() == VisibilityModifiers.API);

    // remove exported packages
    IBundleProjectService service = ProjectUtils.getBundleProjectService();
    IBundleProjectDescription description = service.getDescription(project.getProject());
    description.setPackageExports(null);
    description.apply(null);

    // check the API description
    annot = getTestProjectApiDescription().resolveAnnotations(Factory.packageDescriptor("export1"));
    assertNotNull("should still be an annotation for the package", annot);
    assertTrue(
        "unexported package must be private", VisibilityModifiers.isPrivate(annot.getVisibility()));
  }
  protected void checkRequiredBundles() {
    IProject project = getDomainClass().getFragmentRoot().getJavaProject().getProject();
    BundleContext context = FrameworkUtil.getBundle(NewAddonClassWizard.class).getBundleContext();
    ServiceReference<IBundleProjectService> ref =
        context.getServiceReference(IBundleProjectService.class);
    IBundleProjectService service = context.getService(ref);
    try {
      IBundleProjectDescription description = service.getDescription(project);
      Set<String> requiredBundles = getRequiredBundles();
      IRequiredBundleDescription[] arTmp = description.getRequiredBundles();
      List<IRequiredBundleDescription> descs = new ArrayList<IRequiredBundleDescription>();
      if (arTmp != null) {
        descs.addAll(Arrays.asList(arTmp));
      }
      for (IRequiredBundleDescription bd : descs) {
        requiredBundles.remove(bd.getName());
      }

      if (requiredBundles.size() > 0) {
        for (String b : requiredBundles) {
          descs.add(service.newRequiredBundle(b, null, false, false));
        }
        description.setRequiredBundles(descs.toArray(new IRequiredBundleDescription[0]));
        description.apply(new NullProgressMonitor());
      }
    } catch (CoreException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
 /**
  * Adds an entry to the bundle class path header
  *
  * @param project the project
  * @param entry the entry to append
  * @throws CoreException
  */
 public static void addBundleClasspathEntry(IProject project, IBundleClasspathEntry entry)
     throws CoreException {
   IBundleProjectDescription description = getBundleProjectService().getDescription(project);
   IBundleClasspathEntry[] classpath = description.getBundleClasspath();
   IBundleClasspathEntry[] next = new IBundleClasspathEntry[classpath.length + 1];
   System.arraycopy(classpath, 0, next, 0, classpath.length);
   next[next.length - 1] = entry;
   description.setBundleClasspath(next);
   description.apply(null);
 }
 /**
  * Removes the given package from the exported packages header, if it exists.
  *
  * <p>This method is not safe to use in a head-less manner.
  *
  * @param project the project to remove the package from
  * @param packagename the name of the package to remove from the export package header
  */
 public static void removeExportedPackage(IProject project, String packagename)
     throws CoreException {
   IBundleProjectDescription description = getBundleProjectService().getDescription(project);
   IPackageExportDescription[] exports = description.getPackageExports();
   if (exports != null) {
     List<IPackageExportDescription> list = new ArrayList<IPackageExportDescription>();
     for (int i = 0; i < exports.length; i++) {
       if (!packagename.equals(exports[i].getName())) {
         list.add(exports[i]);
       }
     }
     if (list.size() < exports.length) {
       description.setPackageExports(
           (IPackageExportDescription[]) list.toArray(new IPackageExportDescription[list.size()]));
       description.apply(null);
     }
   }
 }
 /**
  * Adds a new exported package to the manifest.
  *
  * <p>This method is not safe to use in a head-less manner.
  *
  * @param project the project to get the manifest information from
  * @param packagename the fully qualified name of the package to add
  * @param internal if the added package should be internal or not
  * @param friends a listing of friends for this exported package
  * @throws CoreException if something bad happens
  */
 public static void addExportedPackage(
     IProject project, String packagename, boolean internal, String[] friends)
     throws CoreException {
   if (!project.exists() || packagename == null) {
     // do no work
     return;
   }
   IBundleProjectService service = getBundleProjectService();
   IBundleProjectDescription description = service.getDescription(project);
   IPackageExportDescription[] exports = description.getPackageExports();
   List<IPackageExportDescription> list = new ArrayList<IPackageExportDescription>();
   if (exports != null) {
     for (int i = 0; i < exports.length; i++) {
       list.add(exports[i]);
     }
   }
   list.add(service.newPackageExport(packagename, null, !internal, friends));
   description.setPackageExports(
       (IPackageExportDescription[]) list.toArray(new IPackageExportDescription[list.size()]));
   description.apply(null);
   AbstractApiTest.waitForAutoBuild();
 }
  /** Tests removing a library from the classpath of a project */
  public void testWPUpdateLibraryRemovedFromClasspath() throws Exception {
    IPath libPath = null;
    try {
      IJavaProject project = getTestingProject();
      assertNotNull("The testing project must exist", project);

      // add to classpath
      IFolder folder = assertTestLibrary(project, new Path("libx"), "component.a_1.0.0.jar");
      IApiComponent component = getWorkspaceBaseline().getApiComponent(project.getElementName());
      assertNotNull("the workspace component must exist", component);
      int before = component.getApiTypeContainers().length;
      libPath = folder.getFullPath().append("component.a_1.0.0.jar");

      // remove classpath entry
      ProjectUtils.removeFromClasspath(project, JavaCore.newLibraryEntry(libPath, null, null));
      waitForAutoBuild();

      // remove from bundle class path
      IBundleProjectService service = ProjectUtils.getBundleProjectService();
      IBundleProjectDescription description = service.getDescription(project.getProject());
      description.setBundleClasspath(
          new IBundleClasspathEntry[] {
            service.newBundleClasspathEntry(new Path(ProjectUtils.SRC_FOLDER), null, null)
          });
      description.apply(null);
      waitForAutoBuild();

      // retrieve updated component
      component = getWorkspaceBaseline().getApiComponent(project.getElementName());
      assertTrue(
          "there must be less containers after the removal",
          before > component.getApiTypeContainers().length);
    } finally {
      if (libPath != null) {
        FileUtils.delete(libPath.toOSString());
      }
    }
  }