private static ServiceReferenceDTO getServiceReferenceDTO(ServiceReference<?> ref) {
   if (ref == null) {
     return null;
   }
   Bundle b = ref.getBundle();
   if (b == null) {
     // service has been unregistered
     return null;
   }
   ServiceReferenceDTO dto = new ServiceReferenceDTO();
   dto.bundle = b.getBundleId();
   String[] keys = ref.getPropertyKeys();
   Map<String, Object> properties = newMap(keys.length);
   for (String k : keys) {
     Object v = ref.getProperty(k);
     if (Constants.SERVICE_ID.equals(k)) {
       dto.id = ((Long) v).longValue();
     }
     properties.put(k, mapValue(v));
   }
   dto.properties = properties;
   Bundle[] using = ref.getUsingBundles();
   final int length = (using == null) ? 0 : using.length;
   long[] usingBundles = new long[length];
   for (int i = 0; i < length; i++) {
     usingBundles[i] = using[i].getBundleId();
   }
   dto.usingBundles = usingBundles;
   return dto;
 }
 private BundleWiringDTO getBundleWiringDTO(BundleWiring wiring) {
   if (wiring == null) {
     return null;
   }
   BundleWiringDTO dto = new BundleWiringDTO();
   dto.bundle = wiring.getBundle().getBundleId();
   dto.root = getWiringId(wiring);
   dto.nodes = new HashSet<BundleWiringDTO.NodeDTO>(wiringnodes.values());
   dto.resources = new HashSet<BundleRevisionDTO>(resources.values());
   return dto;
 }
 private static Object mapValue(Object v) {
   if ((v == null)
       || v instanceof Number
       || v instanceof Boolean
       || v instanceof Character
       || v instanceof String
       || v instanceof DTO) {
     return v;
   }
   if (v instanceof Map) {
     Map<?, ?> m = (Map<?, ?>) v;
     Map<Object, Object> map = newMap(m.size());
     for (Map.Entry<?, ?> e : m.entrySet()) {
       map.put(mapValue(e.getKey()), mapValue(e.getValue()));
     }
     return map;
   }
   if (v instanceof List) {
     List<?> c = (List<?>) v;
     List<Object> list = newList(c.size());
     for (Object o : c) {
       list.add(mapValue(o));
     }
     return list;
   }
   if (v instanceof Set) {
     Set<?> c = (Set<?>) v;
     Set<Object> set = newSet(c.size());
     for (Object o : c) {
       set.add(mapValue(o));
     }
     return set;
   }
   if (v.getClass().isArray()) {
     final int length = Array.getLength(v);
     final Class<?> componentType = mapComponentType(v.getClass().getComponentType());
     Object array = Array.newInstance(componentType, length);
     for (int i = 0; i < length; i++) {
       Array.set(array, i, mapValue(Array.get(v, i)));
     }
     return array;
   }
   return String.valueOf(v);
 }
 private BundleRevisionDTO getBundleRevisionDTO(BundleRevision revision) {
   if (revision == null) {
     return null;
   }
   BundleRevisionDTO dto = resources.get(revision);
   if (dto != null) {
     return dto;
   }
   dto = new BundleRevisionDTO();
   dto.id = identifier(revision);
   resources.put(revision, dto);
   dto.bundle = revision.getBundle().getBundleId();
   dto.symbolicName = revision.getSymbolicName();
   dto.type = revision.getTypes();
   dto.version = revision.getVersion().toString();
   dto.capabilities = getListCapabilityDTO(revision.getDeclaredCapabilities(null));
   dto.requirements = getListRequirementDTO(revision.getDeclaredRequirements(null));
   return dto;
 }
 private BundleWiringDTO.NodeDTO getBundleWiringNodeDTO(BundleWiring wiring) {
   if (wiring == null) {
     return null;
   }
   BundleWiringDTO.NodeDTO dto = wiringnodes.get(wiring);
   if (dto != null) {
     return dto;
   }
   dto = new BundleWiringDTO.NodeDTO();
   dto.id = identifier(wiring);
   wiringnodes.put(wiring, dto);
   dto.current = wiring.isCurrent();
   dto.inUse = wiring.isInUse();
   dto.resource = getResourceId(wiring.getRevision());
   dto.capabilities = getListCapabilityRefDTO(wiring.getCapabilities(null));
   dto.requirements = getListRequirementRefDTO(wiring.getRequirements(null));
   dto.providedWires = getListBundleWireDTO(wiring.getProvidedWires(null));
   dto.requiredWires = getListBundleWireDTO(wiring.getRequiredWires(null));
   return dto;
 }
 /**
  * Assumes the input map always has String keys and the values are of types: String, Version,
  * Long, Double or List of the previous types. Lists are copied and Version objects are converted
  * to String objects.
  */
 private static Map<String, Object> newAttributesMapDTO(Map<String, Object> map) {
   Map<String, Object> dto = new HashMap<String, Object>(map);
   /* Lists are copied and Version objects are converted to String objects. */
   for (Map.Entry<String, Object> entry : dto.entrySet()) {
     Object value = entry.getValue();
     if (value instanceof Version) {
       entry.setValue(String.valueOf(value));
       continue;
     }
     if (value instanceof List) {
       List<Object> newList = new ArrayList<Object>((List<?>) value);
       for (ListIterator<Object> iter = newList.listIterator(); iter.hasNext(); ) {
         Object element = iter.next();
         if (element instanceof Version) {
           iter.set(String.valueOf(element));
         }
       }
       entry.setValue(newList);
       continue;
     }
   }
   return dto;
 }
	public void testSingleBundleRegions() throws BundleException, InvalidSyntaxException, InterruptedException {
		// get the system region
		Region systemRegion = digraph.getRegion(0);
		Map<String, Bundle> bundles = new HashMap<String, Bundle>();
		// create a disconnected test region for each test bundle
		for (String location : ALL) {
			Region testRegion = digraph.createRegion(location);
			bundles.put(location, bundleInstaller.installBundle(location, testRegion));
			// Import the system bundle from the systemRegion
			digraph.connect(testRegion, digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_BUNDLE_NAMESPACE, "(id=0)").build(), systemRegion);
			// must import Boolean services into systemRegion to test
			digraph.connect(systemRegion, digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_SERVICE_NAMESPACE, "(objectClass=java.lang.Boolean)").build(), testRegion);
		}

		bundleInstaller.resolveBundles(bundles.values().toArray(new Bundle[bundles.size()]));
		assertEquals(PP1, Bundle.RESOLVED, bundles.get(PP1).getState());
		assertEquals(SP1, Bundle.INSTALLED, bundles.get(SP1).getState());
		assertEquals(CP1, Bundle.RESOLVED, bundles.get(CP1).getState());
		assertEquals(PP2, Bundle.INSTALLED, bundles.get(PP2).getState());
		assertEquals(SP2, Bundle.INSTALLED, bundles.get(SP2).getState());
		assertEquals(CP2, Bundle.INSTALLED, bundles.get(CP2).getState());
		assertEquals(BC1, Bundle.INSTALLED, bundles.get(BC1).getState());
		assertEquals(SC1, Bundle.INSTALLED, bundles.get(SC1).getState());
		assertEquals(CC1, Bundle.INSTALLED, bundles.get(CC1).getState());

		// now make the necessary connections
		// SP1
		digraph.connect(digraph.getRegion(SP1), digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_PACKAGE_NAMESPACE, "(" + RegionFilter.VISIBLE_PACKAGE_NAMESPACE + "=pkg1.*)").build(), digraph.getRegion(PP1));
		// PP2
		digraph.connect(digraph.getRegion(PP2), digraph.createRegionFilterBuilder().allow(CP1, "(name=" + CP1 + ")").build(), digraph.getRegion(CP1));
		// SP2
		digraph.connect(digraph.getRegion(SP2), digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_PACKAGE_NAMESPACE, "(" + RegionFilter.VISIBLE_PACKAGE_NAMESPACE + "=pkg2.*)").build(), digraph.getRegion(PP2));
		// CP2
		digraph.connect(digraph.getRegion(CP2), digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_PACKAGE_NAMESPACE, "(" + RegionFilter.VISIBLE_PACKAGE_NAMESPACE + "=pkg1.*)").build(), digraph.getRegion(PP1));
		digraph.connect(digraph.getRegion(CP2), digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_SERVICE_NAMESPACE, "(" + Constants.OBJECTCLASS + "=pkg1.*)").build(), digraph.getRegion(SP1));
		// PC1
		digraph.connect(digraph.getRegion(PC1), digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_PACKAGE_NAMESPACE, "(" + RegionFilter.VISIBLE_PACKAGE_NAMESPACE + "=pkg2.*)").build(), digraph.getRegion(PP2));
		// BC1
		digraph.connect(digraph.getRegion(BC1), digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_REQUIRE_NAMESPACE, "(" + RegionFilter.VISIBLE_REQUIRE_NAMESPACE + "=" + PP2 + ")").build(), digraph.getRegion(PP2));
		// SC1
		digraph.connect(digraph.getRegion(SC1), digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_PACKAGE_NAMESPACE, "(" + RegionFilter.VISIBLE_PACKAGE_NAMESPACE + "=pkg2.*)").build(), digraph.getRegion(PP2));
		digraph.connect(digraph.getRegion(SC1), digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_SERVICE_NAMESPACE, "(" + Constants.OBJECTCLASS + "=pkg2.*)").build(), digraph.getRegion(SP2));
		// CC1
		digraph.connect(digraph.getRegion(CC1), digraph.createRegionFilterBuilder().allow(CP2, "(name=" + CP2 + ")").build(), digraph.getRegion(CP2));

		bundleInstaller.resolveBundles(bundles.values().toArray(new Bundle[bundles.size()]));
		for (Bundle bundle : bundles.values()) {
			assertEquals("Bundle did not resolve: " + bundle.getSymbolicName(), Bundle.RESOLVED, bundle.getState());
			bundle.start();
		}
		BundleContext context = getContext();
		ServiceTracker<Boolean, Boolean> cp2Tracker = new ServiceTracker<Boolean, Boolean>(context, context.createFilter("(&(objectClass=java.lang.Boolean)(bundle.id=" + bundles.get(CP2).getBundleId() + "))"), null);
		ServiceTracker<Boolean, Boolean> sc1Tracker = new ServiceTracker<Boolean, Boolean>(context, context.createFilter("(&(objectClass=java.lang.Boolean)(bundle.id=" + bundles.get(SC1).getBundleId() + "))"), null);

		cp2Tracker.open();
		sc1Tracker.open();

		assertNotNull("The cp2 bundle never found the service.", cp2Tracker.waitForService(2000));
		assertNotNull("The sc1 bundle never found the service.", sc1Tracker.waitForService(2000));
		cp2Tracker.close();
		sc1Tracker.close();
	}
	private void doCyclicRegions(int numLevels) throws BundleException, InvalidSyntaxException, InterruptedException {
		String regionName1 = getName() + "_1";
		String regionName2 = getName() + "_2";
		// get the system region
		Region systemRegion = digraph.getRegion(0);
		// create two regions to hold the bundles
		Region testRegion1 = digraph.createRegion(regionName1);
		Region testRegion2 = digraph.createRegion(regionName2);
		// connect to the system bundle
		testRegion1.connectRegion(systemRegion, digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_BUNDLE_NAMESPACE, "(id=0)").build());
		testRegion2.connectRegion(systemRegion, digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_BUNDLE_NAMESPACE, "(id=0)").build());
		// must import Boolean services into systemRegion to test
		systemRegion.connectRegion(testRegion1, digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_SERVICE_NAMESPACE, "(objectClass=java.lang.Boolean)").build());
		systemRegion.connectRegion(testRegion2, digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_SERVICE_NAMESPACE, "(objectClass=java.lang.Boolean)").build());

		Map<String, Bundle> bundles = new HashMap<String, Bundle>();
		// add bundles to region1
		bundles.put(PP1, bundleInstaller.installBundle(PP1, testRegion1));
		bundles.put(SP2, bundleInstaller.installBundle(SP2, testRegion1));
		bundles.put(CP2, bundleInstaller.installBundle(CP2, testRegion1));
		bundles.put(PC1, bundleInstaller.installBundle(PC1, testRegion1));
		bundles.put(BC1, bundleInstaller.installBundle(BC1, testRegion1));

		// add bundles to region2
		bundles.put(SP1, bundleInstaller.installBundle(SP1, testRegion2));
		bundles.put(CP1, bundleInstaller.installBundle(CP1, testRegion2));
		bundles.put(PP2, bundleInstaller.installBundle(PP2, testRegion2));
		bundles.put(SC1, bundleInstaller.installBundle(SC1, testRegion2));
		bundles.put(CC1, bundleInstaller.installBundle(CC1, testRegion2));

		RegionFilterBuilder testRegionFilter1 = digraph.createRegionFilterBuilder();
		// SP2 -> PP2
		testRegionFilter1.allow(RegionFilter.VISIBLE_PACKAGE_NAMESPACE, "(" + RegionFilter.VISIBLE_PACKAGE_NAMESPACE + "=pkg2.*)");
		// CP2 -> SP1
		testRegionFilter1.allow(RegionFilter.VISIBLE_SERVICE_NAMESPACE, "(" + Constants.OBJECTCLASS + "=pkg1.*)");
		// PC1 -> PP2
		// this is not needed because we already import pkg2.* above
		//testRegionFilter1.allow(RegionFilter.VISIBLE_PACKAGE_NAMESPACE, "(" + RegionFilter.VISIBLE_PACKAGE_NAMESPACE + "=pkg2.*)");
		// BC1 -> PP2
		testRegionFilter1.allow(RegionFilter.VISIBLE_REQUIRE_NAMESPACE, "(" + RegionFilter.VISIBLE_REQUIRE_NAMESPACE + "=" + PP2 + ")");

		RegionFilterBuilder testRegionFilter2 = digraph.createRegionFilterBuilder();
		//SP1 -> PP1
		testRegionFilter2.allow(RegionFilter.VISIBLE_PACKAGE_NAMESPACE, "(" + RegionFilter.VISIBLE_PACKAGE_NAMESPACE + "=pkg1.*)");
		//SC1 -> SP2
		testRegionFilter2.allow(RegionFilter.VISIBLE_SERVICE_NAMESPACE, "(" + Constants.OBJECTCLASS + "=pkg2.*)");
		//CC1 -> CP2
		testRegionFilter2.allow(CP2, "(name=" + CP2 + ")");

		Region r1, r2 = null;
		for (int i = 0; i <= numLevels; i++) {
			r1 = (i > 0) ? r2 : testRegion1;
			r2 = (i < numLevels) ? digraph.createRegion(getName() + "_level_" + i) : testRegion2;
			r1.connectRegion(r2, testRegionFilter1.build());
			r2.connectRegion(r1, testRegionFilter2.build());
		}

		bundleInstaller.resolveBundles(bundles.values().toArray(new Bundle[bundles.size()]));
		for (Bundle bundle : bundles.values()) {
			assertEquals("Bundle did not resolve: " + bundle.getSymbolicName(), Bundle.RESOLVED, bundle.getState());
			bundle.start();
		}
		BundleContext context = getContext();
		ServiceTracker<Boolean, Boolean> cp2Tracker = new ServiceTracker<Boolean, Boolean>(context, context.createFilter("(&(objectClass=java.lang.Boolean)(bundle.id=" + bundles.get(CP2).getBundleId() + "))"), null);
		ServiceTracker<Boolean, Boolean> sc1Tracker = new ServiceTracker<Boolean, Boolean>(context, context.createFilter("(&(objectClass=java.lang.Boolean)(bundle.id=" + bundles.get(SC1).getBundleId() + "))"), null);

		cp2Tracker.open();
		sc1Tracker.open();

		assertNotNull("The cp2 bundle never found the service.", cp2Tracker.waitForService(2000));
		assertNotNull("The sc1 bundle never found the service.", sc1Tracker.waitForService(2000));
		cp2Tracker.close();
		sc1Tracker.close();
	}
	public void testPersistence() throws BundleException, InvalidSyntaxException {
		// get the system region
		Region systemRegion = digraph.getRegion(0);
		Map<String, Bundle> bundles = new HashMap<String, Bundle>();
		// create a disconnected test region for each test bundle
		for (String location : ALL) {
			Region testRegion = digraph.createRegion(location);
			bundles.put(location, bundleInstaller.installBundle(location, testRegion));
			// Import the system bundle from the systemRegion
			digraph.connect(testRegion, digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_BUNDLE_NAMESPACE, "(id=0)").build(), systemRegion);
			// must import Boolean services into systemRegion to test
			digraph.connect(systemRegion, digraph.createRegionFilterBuilder().allow(RegionFilter.VISIBLE_SERVICE_NAMESPACE, "(objectClass=java.lang.Boolean)").build(), testRegion);
		}

		bundleInstaller.resolveBundles(bundles.values().toArray(new Bundle[bundles.size()]));
		assertEquals(PP1, Bundle.RESOLVED, bundles.get(PP1).getState());
		assertEquals(SP1, Bundle.INSTALLED, bundles.get(SP1).getState());
		assertEquals(CP1, Bundle.RESOLVED, bundles.get(CP1).getState());
		assertEquals(PP2, Bundle.INSTALLED, bundles.get(PP2).getState());
		assertEquals(SP2, Bundle.INSTALLED, bundles.get(SP2).getState());
		assertEquals(CP2, Bundle.INSTALLED, bundles.get(CP2).getState());
		assertEquals(BC1, Bundle.INSTALLED, bundles.get(BC1).getState());
		assertEquals(SC1, Bundle.INSTALLED, bundles.get(SC1).getState());
		assertEquals(CC1, Bundle.INSTALLED, bundles.get(CC1).getState());

		regionBundle.stop();
		bundleInstaller.resolveBundles(bundles.values().toArray(new Bundle[bundles.size()]));
		assertEquals(PP1, Bundle.RESOLVED, bundles.get(PP1).getState());
		assertEquals(SP1, Bundle.RESOLVED, bundles.get(SP1).getState());
		assertEquals(CP1, Bundle.RESOLVED, bundles.get(CP1).getState());
		assertEquals(PP2, Bundle.RESOLVED, bundles.get(PP2).getState());
		assertEquals(SP2, Bundle.RESOLVED, bundles.get(SP2).getState());
		assertEquals(CP2, Bundle.RESOLVED, bundles.get(CP2).getState());
		assertEquals(BC1, Bundle.RESOLVED, bundles.get(BC1).getState());
		assertEquals(SC1, Bundle.RESOLVED, bundles.get(SC1).getState());
		assertEquals(CC1, Bundle.RESOLVED, bundles.get(CC1).getState());

		startRegionBundle();

		bundleInstaller.refreshPackages(bundles.values().toArray(new Bundle[bundles.size()]));
		assertEquals(PP1, Bundle.RESOLVED, bundles.get(PP1).getState());
		assertEquals(SP1, Bundle.INSTALLED, bundles.get(SP1).getState());
		assertEquals(CP1, Bundle.RESOLVED, bundles.get(CP1).getState());
		assertEquals(PP2, Bundle.INSTALLED, bundles.get(PP2).getState());
		assertEquals(SP2, Bundle.INSTALLED, bundles.get(SP2).getState());
		assertEquals(CP2, Bundle.INSTALLED, bundles.get(CP2).getState());
		assertEquals(BC1, Bundle.INSTALLED, bundles.get(BC1).getState());
		assertEquals(SC1, Bundle.INSTALLED, bundles.get(SC1).getState());
		assertEquals(CC1, Bundle.INSTALLED, bundles.get(CC1).getState());
	}