/**
 * Copyright (C) 2010, FuseSource Corp.  All rights reserved.
 * http://fusesource.com
 *
 * The software in this package is published under the terms of the
 * AGPL license a copy of which has been included with this distribution
 * in the license.txt file.
 */
package org.fusesource.fabric.fab.osgi.url.internal;

import aQute.lib.osgi.Analyzer;
import org.apache.felix.utils.version.VersionCleaner;
import org.fusesource.fabric.fab.util.Strings;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Version;

import java.util.*;

/**
 * Some bundle helper methods
 */
public class Bundles {

    public static boolean isInstalled(BundleContext bundleContext, String name, String version) {
        return findBundle(bundleContext, name, version) != null;
    }

    /**
     * Filter out any packages which are already installed as a version which matches the imported version range
     *
     * @return the filtered set of packages which are not installed
     */
    public static Set<String> filterInstalled(BundleContext bundleContext, Collection<String> packages, VersionResolver resolver) {
        HashSet<String> rc = new HashSet<String>(packages);
        for (Bundle bundle : bundleContext.getBundles()) {
            if (rc.isEmpty()) {
                break;
            }
            String value = (String) bundle.getHeaders().get("Export-Package");
            if (Strings.notEmpty(value)) {
                Map<String, Map<String, String>> values = new Analyzer().parseHeader(value);
                for (String packageName : packages) {
                    Map<String, String> map = values.get(packageName);
                    if (map != null) {
                        String version = map.get("version");
                        if (version != null) {
                            String importedVersion = resolver.resolvePackageVersion(packageName);
                            if (importedVersion != null) {
                                if (Versions.inRange(version, importedVersion)) {
                                    rc.remove(packageName);
                                }
                            }
                        }
                    }
                }
            }
        }
        return rc;
    }

    public static Bundle findBundle(BundleContext bundleContext, String name, String version) {
        Version v = new Version(VersionCleaner.clean(version));
        Bundle[] bundles = bundleContext.getBundles();
        for (Bundle bundle : bundles) {
            // TODO should be using ranges here!!
            if (bundle.getSymbolicName().equals(name) && bundle.getVersion().equals(v)) {
                return bundle;
            }
        }
        return null;
    }
}

@@ -396,24 +396,71 @@
 ionCleaner;%0A
+import org.fusesource.fabric.fab.util.Objects;%0A
 import org.f
@@ -2668,16 +2668,30 @@
      if 
+(Objects.equal
 (bundle.
@@ -2707,24 +2707,18 @@
 icName()
-.equals(
+, 
 name) &&
@@ -2718,16 +2718,30 @@
 ame) && 
+Objects.equal(
 bundle.g
@@ -2755,16 +2755,10 @@
 on()
-.equals(
+, 
 v)) 

fix possbile NPE