protected List<BundleHandler> listBundleHandlers(BundleContext context)
      throws MalformedURLException {
    JsonValue bundle = getLauncherConfiguration().get("bundle");
    BundleHandlerBuilder defaultBuilder = BundleHandlerBuilder.newBuilder(bundle.get("default"));

    List<BundleHandler> result = new ArrayList<BundleHandler>();

    URI installDirectory = getInstallURI();

    for (JsonValue container : bundle.get("containers")) {
      BundleHandlerBuilder innerBuilder =
          BundleHandlerBuilder.newBuilder(container, defaultBuilder);

      String location = container.get("location").required().asString();
      if (location.toLowerCase().endsWith(".zip")) {
        File inputFile = getFileForPath(location, installDirectory);
        for (URL url :
            ConfigurationUtil.getZipFileListing(
                inputFile.toURI().toURL(),
                container.get("includes").asList(String.class),
                container.get("excludes").asList(String.class))) {
          result.add(innerBuilder.build(url));
        }

      } else if (location.toLowerCase().endsWith(".jar")) {
        File inputFile = getFileForPath(location, installDirectory);
        result.add(innerBuilder.build(inputFile.toURI().toURL()));
      } else {
        DirectoryScanner scanner = new DirectoryScanner();
        scanner.setBasedir(getFileForPath(location, installDirectory));
        if (container.isDefined("includes")) {
          List<String> includes = container.get("includes").asList(String.class);
          scanner.setIncludes(includes.toArray(new String[includes.size()]));
        }
        if (container.isDefined("excludes")) {
          List<String> includes = container.get("excludes").asList(String.class);
          scanner.setExcludes(includes.toArray(new String[includes.size()]));
        }
        scanner.scan();

        for (String bundleLocation : scanner.getIncludedFiles()) {
          BundleHandler newHandler =
              innerBuilder.build(
                  scanner
                      .getBasedir()
                      .toURI()
                      .resolve(bundleLocation.replaceAll("\\\\", "/"))
                      .toURL());
          for (BundleHandler handler : result) {
            if (newHandler.getBundleUrl().equals(handler.getBundleUrl())) {
              if (newHandler.getActions().equals(handler.getActions())
                  && newHandler.getStartLevel() == newHandler.getStartLevel()) {
                // Do not duplicate
                newHandler = null;
                break;
              } else {
                StringBuilder sb = new StringBuilder("Controversial provisioning between ");
                sb.append(handler).append(" and ").append(newHandler);
                throw new IllegalArgumentException(sb.toString());
              }
            }
          }
          if (null != newHandler) {
            result.add(newHandler);
          }
        }
      }
    }
    return result;
  }