/**
  * Adds Error Parser extension to the global repository. Note that this function will "pollute"
  * the working environment and the error parser will be seen by other test cases as well.
  *
  * @param shortId - last portion of ID with which error parser will be added.
  * @param cl - Error Parser class
  * @return - full ID of the error parser (generated by the method).
  */
 private static String addErrorParserExtension(String shortId, Class cl) {
   String ext =
       "<plugin><extension id=\""
           + shortId
           + "\" name=\""
           + shortId
           + "\" point=\"org.eclipse.cdt.core.ErrorParser\">"
           + "<errorparser class=\""
           + cl.getName()
           + "\"/>"
           + "</extension></plugin>";
   IContributor contributor =
       ContributorFactoryOSGi.createContributor(CTestPlugin.getDefault().getBundle());
   boolean added =
       Platform.getExtensionRegistry()
           .addContribution(
               new ByteArrayInputStream(ext.getBytes()),
               contributor,
               false,
               shortId,
               null,
               ((ExtensionRegistry) Platform.getExtensionRegistry()).getTemporaryUserToken());
   assertTrue("failed to add extension", added);
   String fullId = "org.eclipse.cdt.core.tests." + shortId;
   IErrorParser[] errorParser = CCorePlugin.getDefault().getErrorParser(fullId);
   assertTrue(errorParser.length > 0);
   return fullId;
 }
  private Object invokeGetter(final Method method) {
    final Class<?> resultType = method.getReturnType();

    if (IConfigurationElement.class == resultType) {
      return config;
    } else if (Bundle.class == resultType) {
      return ContributorFactoryOSGi.resolve(config.getContributor());
    }

    // map bean name to an XML attribute
    final String key = mapName(method, findPropertyName(method));
    final String value = mapContent(config, key);

    if (null != value) {

      if (String.class == resultType) {
        return value;
      } else if (Class.class == resultType) {
        return loadExtensionClass(config, value);
      } else if (resultType.isPrimitive()) {
        return valueOf(resultType, value);
      }

      try {
        return config.createExecutableExtension(key);
      } catch (final CoreException e) {
        /* try nested getter */
      } // NOPMD
    }

    return invokeNestedGetter(resultType, key);
  }
  /**
   * Refreshes all exported packages of the given bundles. This must be called after installing the
   * bundle.
   *
   * @param bundles Bundles which exported packages are to be refreshed.
   */
  @SuppressWarnings("restriction")
  void refreshPackages(Bundle[] bundles) {
    BundleContext context = AcceleoCommonPlugin.getDefault().getContext();
    ServiceReference packageAdminReference =
        context.getServiceReference(PackageAdmin.class.getName());
    PackageAdmin packageAdmin = null;
    if (packageAdminReference != null) {
      packageAdmin = (PackageAdmin) context.getService(packageAdminReference);
    }

    if (packageAdmin != null) {
      final boolean[] flag =
          new boolean[] {
            false,
          };
      FrameworkListener listener =
          new FrameworkListener() {
            public void frameworkEvent(FrameworkEvent event) {
              if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
                synchronized (flag) {
                  flag[0] = true;
                  flag.notifyAll();
                }
              }
            }
          };

      /*
       * Hack-ish : Make sure the contributions from this bundle won't be parsed. When installing a
       * bundle, the EclipseBundleListener will _always_ parse the plugin.xml and notify the extension
       * registry (and its listeners) of the new contributions. Problem is : some bundles listen to new
       * contributions, but ignore the event of contribution removals (when we uninstall the bundle). We
       * would thus end with "invalid registry object" exceptions thrown ... with no way to prevent or
       * fix them whatsoever. Equinox does not provide us with an API to disable the contributions from
       * the bundle we're installing, temporarily disable the extension listeners... or any other way to
       * workaround this registry issue. We'll then make use of the fact that the EclipseBundleListener
       * does not add contributions from a contributor which has already been added: we'll add the
       * contributor beforehand with an empty plugin.xml, disabling all potential contributions this
       * bundle would have made otherwise.
       */

      if (bundles != null && Platform.getExtensionRegistry() instanceof IDynamicExtensionRegistry) {
        IExtensionRegistry registry = Platform.getExtensionRegistry();
        for (Bundle bundle : bundles) {
          IContributor contributor = ContributorFactoryOSGi.createContributor(bundle);
          if (!((IDynamicExtensionRegistry) registry).hasContributor(contributor)) {
            registry.addContribution(
                new ByteArrayInputStream(EMPTY_PLUGIN_XML.getBytes()),
                contributor,
                false,
                null,
                null,
                ((ExtensionRegistry) registry).getTemporaryUserToken());
          }
        }
      }

      context.addFrameworkListener(listener);
      packageAdmin.refreshPackages(bundles);
      synchronized (flag) {
        while (!flag[0]) {
          try {
            flag.wait(OSGI_TIMEOUT);
          } catch (InterruptedException e) {
            // discard
            break;
          }
        }
      }
      context.removeFrameworkListener(listener);
      if (packageAdminReference != null) {
        context.ungetService(packageAdminReference);
      }
    }
  }