diff --git a/deviceaccess/pom.xml b/deviceaccess/pom.xml
index e22b55a..9968fc2 100644
--- a/deviceaccess/pom.xml
+++ b/deviceaccess/pom.xml
@@ -18,25 +18,35 @@
  under the License.
 -->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>felix</artifactId>
-        <version>1.0.4</version>
-        <relativePath>../pom/pom.xml</relativePath>
-    </parent>
 
-    <artifactId>org.apache.felix.devicemanager</artifactId>
-    <version>0.9.0-SNAPSHOT</version>
-    <packaging>bundle</packaging>
+  <modelVersion>4.0.0</modelVersion>
 
-    <name>Apache Felix Device Manager</name>
-    <description>
-        Implementation of the OSGi Device Access Specification 1.1
-    </description>
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>1.0.5-SNAPSHOT</version>
+    <relativePath>../pom/pom.xml</relativePath>
+  </parent>
+
+  <artifactId>org.apache.felix.devicemanager</artifactId>
+  <version>0.9.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <name>Apache Felix Device Manager</name>
+
+  <description>
+      Implementation of the OSGi Device Access Specification 1.1
+  </description>
+
   <dependencies>
     <dependency>
       <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.framework</artifactId>
+      <version>1.6.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
       <artifactId>org.osgi.core</artifactId>
       <version>1.0.0</version>
       <scope>provided</scope>
@@ -50,17 +60,14 @@
     <dependency>
       <groupId>${pom.groupId}</groupId>
       <artifactId>org.apache.felix.dependencymanager</artifactId>
-      <version>2.0.1-SNAPSHOT</version>
+      <version>2.0.2-SNAPSHOT</version>
       <scope>provided</scope>
     </dependency>
-    </dependencies>
+  </dependencies>
+
   <build>
     <plugins>
       <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <version>2.3</version>
-      </plugin>
-      <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>
         <version>1.4.0</version>
diff --git a/deviceaccess/src/test/java/org/apache/felix/das/ActivatorTest.java b/deviceaccess/src/test/java/org/apache/felix/das/ActivatorTest.java
new file mode 100644
index 0000000..bb1656f
--- /dev/null
+++ b/deviceaccess/src/test/java/org/apache/felix/das/ActivatorTest.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.das;
+
+import org.apache.felix.dependencymanager.DependencyManager;
+import org.apache.felix.dependencymanager.Service;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.osgi.framework.BundleContext;
+
+
+
+/**
+ * 
+ * Tests the Activator.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ActivatorTest {
+
+	
+	
+	private Activator m_activator;
+	
+	@Mock
+	private BundleContext m_context;
+	
+	@Mock
+	private DependencyManager m_manager;
+	
+	@Before
+	public void before() {
+
+		MockitoAnnotations.initMocks(this);
+		m_activator = new Activator();
+		
+	}
+
+	
+	
+	
+	@Test
+	public void VerifyActivatorInit() throws Exception {
+		
+		m_activator.init(m_context, m_manager);
+		
+		Mockito.verify(m_manager).add(Mockito.isA(Service.class));
+		
+	}
+	
+	/**
+	 * Verify we do not actively perform any actions during the destroy.
+	 * 
+	 * @throws Exception
+	 */
+	@Test
+	public void VerifyActivatorDestroy() throws Exception {
+		
+		m_activator.destroy(m_context, m_manager);
+		
+		Mockito.verifyZeroInteractions(m_context);
+		Mockito.verifyZeroInteractions(m_manager);
+		
+	}
+	
+	
+}
diff --git a/deviceaccess/src/test/java/org/apache/felix/das/DeviceManagerTest.java b/deviceaccess/src/test/java/org/apache/felix/das/DeviceManagerTest.java
new file mode 100644
index 0000000..de384b2
--- /dev/null
+++ b/deviceaccess/src/test/java/org/apache/felix/das/DeviceManagerTest.java
@@ -0,0 +1,914 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.das;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.Assert;
+
+import org.apache.felix.das.util.DriverLoader;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.device.Constants;
+import org.osgi.service.device.Device;
+import org.osgi.service.device.Driver;
+import org.osgi.service.device.DriverLocator;
+import org.osgi.service.device.DriverSelector;
+import org.osgi.service.device.Match;
+import org.osgi.service.log.LogService;
+
+
+
+/**
+ * Test the actual implementation.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DeviceManagerTest
+{
+
+	@Mock
+    private DeviceManager m_manager;
+
+	@Mock Bundle m_systemBundle;
+	
+	@Mock
+	private LogService m_log;
+	
+	
+	private BundleContext m_context;
+	
+	
+    private OSGiMock m_osgi;
+
+
+    @Before
+    public void setUp() throws Exception
+    {
+        m_osgi = new OSGiMock();
+
+    	MockitoAnnotations.initMocks(this);
+    	
+    	m_context = m_osgi.getBundleContext();
+    	
+        m_manager = new DeviceManager( m_context );
+        
+        Utils.invoke( m_manager, "init" );
+        
+        Utils.inject( m_manager, LogService.class, m_log );
+        
+        Mockito.when( m_context.getBundle( 0 ) ).thenReturn( m_systemBundle );
+
+        final CountDownLatch latch = new CountDownLatch( 1 );
+
+        Answer<Integer> answer = new Answer<Integer>()
+        {
+        	public Integer answer(InvocationOnMock invocation) throws Throwable
+            {
+                latch.countDown();
+                return Bundle.ACTIVE;
+            }
+        };
+
+        Mockito.when( m_systemBundle.getState() ).thenAnswer( answer );
+
+        Utils.invoke( m_manager, "start" );
+        latch.await( 5, TimeUnit.SECONDS );
+
+        Mockito.when( m_context.installBundle(Mockito.isA( String.class ), ( InputStream ) Mockito.isNull() ) )
+        	.thenThrow(new NullPointerException( "inputstream is null exception" ) );
+    }
+
+
+    @After
+    public void tearDown() throws Exception
+    {
+        Utils.invoke( m_manager, "stop" );
+        Utils.invoke( m_manager, "destroy" );
+    }
+
+    private Driver tstCreateDriver( String driverId, int match ) throws Exception
+    {
+        Properties p = new Properties();
+        p.put( Constants.DRIVER_ID, driverId );
+        p.put( "match", Integer.toString( match ) );
+
+        return tstCreateDriver( p );
+    }
+
+
+    private Driver tstCreateDriver( Properties p ) throws Exception
+    {
+        Driver driver = Mockito.mock( Driver.class );
+        
+        ServiceReference ref = m_osgi.registerService( 
+        		new String[]{ Driver.class.getName() }, driver, p );
+
+        MatchAnswer answer = new MatchAnswer( ref );
+
+        Mockito.when( driver.match( Mockito.isA( ServiceReference.class ) ) )
+        	.thenAnswer( answer );
+        
+        Bundle bundle = m_osgi.getBundle( ref );
+        Mockito.when( bundle.getLocation() )
+        	.thenReturn( 
+            DriverLoader.DRIVER_LOCATION_PREFIX  + p.getProperty( Constants.DRIVER_ID ));
+        
+        return driver;
+    }
+
+
+    private Device tstCreateDevice( String[] cat )
+    {
+        return tstCreateDevice( cat, true );
+    }
+
+
+    private Device tstCreateDevice( String[] cat, boolean isDevice )
+    {
+        Properties p = new Properties();
+        p.put( Constants.DEVICE_CATEGORY, cat );
+        if ( isDevice )
+        {
+            return ( Device ) tstCreateService( p, Device.class );
+        }
+        return tstCreateService( p, Object.class );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private <T> T tstCreateService( Properties p, Class<?> iface )
+    {
+        T svc = ( T ) Mockito.mock( iface, iface.getSimpleName() );
+        
+        m_osgi.registerService( new String[]
+            { iface.getName() }, svc, p );
+        return svc;
+    }
+
+
+    /**
+     * 
+     * prepared all expected behavior for the installation of a dynamic driver
+     * bundle based on an acquired InputStream.
+     * 
+     * 
+     * @param driverId
+     * @param match
+     * @param in
+     * @return
+     * @throws BundleException
+     * @throws Exception
+     */
+    private Driver tstExpectInstallDriverBundle( String driverId, int match, InputStream in ) throws BundleException,
+        Exception
+    {
+
+        Bundle bundle = Mockito.mock( Bundle.class, "driverBundle" );
+        Mockito.when( m_context.installBundle( 
+        		Mockito.eq( "_DD_" + driverId ), Mockito.eq( in ) ) )
+        		.thenReturn( bundle );
+
+        final Driver driver = tstCreateDriver( driverId, match );
+        final ServiceReference driverRef = m_osgi.getReference( driver );
+
+        Answer<Object> answer = new Answer<Object>()
+        {
+        	
+        	public Object answer(InvocationOnMock invocation) throws Throwable
+            {
+                m_manager.driverAdded( driverRef, driver );
+                return null;
+            }
+        };
+
+        //bundle start leads to the addition of the driver to
+        //the device manager.
+        Mockito.doAnswer(answer).when(bundle).start();
+
+        Mockito.when( bundle.getRegisteredServices() )
+        	.thenReturn( new ServiceReference[]{ driverRef } );
+
+        return driver;
+    }
+
+
+    /**
+     * returns a CountDownLatch.
+     * This countdown latch will count down as soon as <code>Device.noDriverFound()</code>
+     * has been called.
+     * @param device the Device
+     * @return the countdown latch
+     */
+    private CountDownLatch tstExpectNoDriverFound( Device device )
+    {
+        final CountDownLatch latch = new CountDownLatch( 1 );
+
+        //countdown when noDriverFound is called
+        Answer<Object> answer = new Answer<Object>()
+        {
+        	public Object answer(InvocationOnMock invocation) throws Throwable
+            {
+                latch.countDown();
+                return null;
+            }
+        };
+
+        Mockito.doAnswer( answer ).when(device).noDriverFound();
+
+        return latch;
+
+    }
+
+
+    private CountDownLatch tstExpectAttach( Driver driver, Object device ) throws Exception
+    {
+        final CountDownLatch latch = new CountDownLatch( 1 );
+        Answer<String> answer = new Answer<String>()
+        {
+            public String answer(InvocationOnMock invocation) throws Throwable
+            {
+                latch.countDown();
+                return null;
+            }
+        };
+
+        //successful attach
+        Mockito.when( driver.attach( m_osgi.getReference( device ) ) )
+        	.thenAnswer( answer );
+
+        return latch;
+    }
+
+    private CountDownLatch tstExpectUnloadDriverBundle( Driver driver ) throws BundleException {
+    	
+    	
+    	final CountDownLatch latch = new CountDownLatch( 1 );
+        Answer<String> answer = new Answer<String>()
+        {
+            public String answer(InvocationOnMock invocation) throws Throwable
+            {
+                latch.countDown();
+                return null;
+            }
+        };
+
+        Bundle bundle = m_osgi.getBundle( m_osgi.getReference( driver ) );
+        
+        Mockito.doAnswer(answer).when( bundle ).uninstall();
+
+        return latch;    	
+    }
+
+    /**
+     * This method generates behavior on the provided DriverLocator.
+     * 
+     * The given driver Ids and their matches are expected as drivers found
+     * by this driver locator.
+     * Also, if a driver is found, we can also expect that loadDriver is called;
+     * resulting in an InputStream. That particular input stream should, when installed
+     * using a bundle context, lead to the registration of a driver with 
+     * the correcsponding driver id.
+     *  
+     * @param locator
+     * @param driverIds
+     * @param matches
+     * @return
+     * @throws Exception
+     */
+    private Map<String, Driver> tstExpectDriverLocatorFor( final DriverLocator locator, final String[] driverIds,
+        int[] matches ) throws Exception
+    {
+
+        Mockito.when( locator.findDrivers( Mockito.isA( Dictionary.class ) ) )
+        	.thenReturn( driverIds );
+
+        Map<String, Driver> drivers = new HashMap<String, Driver>();
+
+        final Map<String, InputStream> streams = new HashMap<String, InputStream>();
+
+        for ( String driverId : driverIds )
+        {
+            InputStream in = Mockito.mock(InputStream.class, "[InputStream for: " + driverId + "]");
+            streams.put( driverId, in );
+        }
+
+        Answer<InputStream> answer = new Answer<InputStream>()
+        {
+        	public InputStream answer(InvocationOnMock invocation) throws Throwable
+            {
+                final String id = invocation.getArguments()[0].toString();
+
+                for ( String driverId : driverIds )
+                {
+                    if ( id.equals( driverId ) )
+                    {
+                        return streams.get( id );
+                    }
+                }
+                throw new IOException( "no such driverId defined in this locator: " + locator );
+            }
+        };
+
+        
+        Mockito.when( locator.loadDriver( Mockito.isA( String.class ) ) )
+        	.thenAnswer( answer );
+
+        int i = 0;
+        for ( String driverId : driverIds )
+        {
+            Driver driver = tstExpectInstallDriverBundle( driverId, matches[i], streams.get( driverId ) );
+            drivers.put( driverId, driver );
+            i++;
+        }
+
+        return drivers;
+
+    }
+
+
+    /**
+     * does not really test anything special, but ensures that the internal
+     * structure is able to parse the addition
+     */
+    @Test
+    public void LocatorAdded()
+    {
+
+        DriverLocator locator = Mockito.mock( DriverLocator.class );
+        m_manager.locatorAdded( locator );
+
+    }
+
+
+    /**
+     * does not really test anything special, but ensures that the internal
+     * structure is able to parse the addition/ removal
+     */
+    @Test
+    public void LocatorRemoved()
+    {
+
+        DriverLocator locator = Mockito.mock( DriverLocator.class );
+
+        m_manager.locatorAdded( locator );
+        m_manager.locatorRemoved( locator );
+
+    }
+
+
+    /**
+     * does not really test anything special, but ensures that the internal
+     * structure is able to parse the addition
+     * @throws Exception 
+     */
+    @Test
+    public void DriverAdded() throws Exception
+    {
+
+        Driver driver = tstCreateDriver( "org.apache.felix.driver-1.0", 1 );
+
+        m_manager.driverAdded( m_osgi.getReference( driver ), driver );
+
+    }
+
+
+    /**
+     * does not really test anything special, but ensures that the internal
+     * structure is able to parse the addition/ removal
+     * @throws Exception 
+     */
+    @Test
+    public void DriverRemoved() throws Exception
+    {
+
+        Driver driver = tstCreateDriver( "org.apache.felix.driver-1.0", 1 );
+
+        ServiceReference ref = m_osgi.getReference( driver );
+
+        m_manager.driverAdded( ref, driver );
+        m_manager.driverRemoved( ref );
+    }
+
+    /**
+     * does not really test anything special, but ensures that the internal
+     * structure is able to parse the addition/ removal
+     * @throws Exception 
+     */
+    @Test
+    public void DeviceRemoved() throws Exception
+    {
+
+    	Properties p = new Properties();
+    	p.put(Constants.DEVICE_CATEGORY, new String[]{"dummy"});
+    	
+        ServiceReference ref = OSGiMock.createReference(p);
+        
+        Object device = new Object();
+
+        m_manager.deviceAdded( ref, device );
+        m_manager.deviceRemoved( ref );
+    }
+
+    /**
+     * does not really test anything special, but ensures that the internal
+     * structure is able to parse the addition/ removal
+     * @throws Exception 
+     */
+    @Test
+    public void DeviceModified() throws Exception
+    {
+
+    	Properties p = new Properties();
+    	p.put(Constants.DEVICE_CATEGORY, new String[]{"dummy"});
+    	
+        ServiceReference ref = OSGiMock.createReference(p);
+        Object device = new Object();
+        
+        m_manager.deviceAdded( ref, new Object() );
+        m_manager.deviceModified(ref, device);
+    }
+    //intended flow, various configurations
+    /**
+     * 	We add a device, but there are no driver locators, so
+     *  the noDriverFound method must be called
+     * @throws InterruptedException 
+     */
+    @Test
+    public void DeviceAddedNoDriverLocator() throws InterruptedException
+    {
+
+        //create a mocked device
+        Device device = tstCreateDevice( new String[]
+            { "org.apache.felix" } );
+
+        CountDownLatch latch = tstExpectNoDriverFound( device );
+
+        m_manager.deviceAdded( m_osgi.getReference( device ), device );
+
+        if ( !latch.await( 5, TimeUnit.SECONDS ) )
+        {
+            Assert.fail( "expected call noDriverFound" );
+        }
+        
+    }
+
+
+    /**
+     * 	We add a device, but there are no driver locators, however, there is a driver
+     *  that matches. Thus an attach must follow.
+     * @throws Exception 
+     */
+    @Test
+    public void DeviceAddedNoDriverLocatorSuccessfulAttach() throws Exception
+    {
+
+        Device device = tstCreateDevice( new String[] { "org.apache.felix" } );
+        Driver driver = tstCreateDriver( "org.apache.felix.driver-1.0", 1 );
+
+        CountDownLatch attachLatch = tstExpectAttach( driver, device );
+
+        m_manager.driverAdded( m_osgi.getReference( driver ), driver );
+        m_manager.deviceAdded( m_osgi.getReference( device ), device );
+
+        if ( !attachLatch.await( 5, TimeUnit.SECONDS ) )
+        {
+            Assert.fail( "expected attach" );
+        }
+
+    }
+
+
+    /**
+     * 	We add a device, but there are no driver locators, however, there is a driver
+     *  but it sadly doesn't match. Thus a <code>noDriverFound()</code> is called.
+     *  
+     * @throws Exception 
+     */
+    @Test
+    public void DeviceAddedNoDriverLocatorAttachFails() throws Exception
+    {
+
+        Device device = tstCreateDevice( new String[] { "org.apache.felix" } );
+        Driver driver = tstCreateDriver( "org.apache.felix.driver-1.0", Device.MATCH_NONE );
+
+        CountDownLatch attachLatch = tstExpectNoDriverFound( device );
+
+        m_manager.driverAdded( m_osgi.getReference( driver ), driver );
+        m_manager.deviceAdded( m_osgi.getReference( device ), device );
+
+        if ( !attachLatch.await( 5, TimeUnit.SECONDS ) )
+        {
+            Assert.fail( "expected attach" );
+        }
+
+    }
+
+
+    /**
+     * We add a device while there's one driverlocator that will successfully
+     * locate and load two driver bundles. We expect a <code>Driver.attach()</code> for 
+     * the best matching driver. There's already a driver loaded that should not match.
+     * 
+     * @throws Exception
+     */
+    @Test
+    public void DeviceAddedWithADriverLocator() throws Exception
+    {
+
+        final String driverId1 = "org.apache.felix.driver-1.0";
+        final String driverId2 = "org.apache.felix.driver-1.1";
+        final String notMatchingButLoadedDriverId = "dotorg.apache.felix.driver-1.0";
+
+
+        DriverLocator locator = Mockito.mock( DriverLocator.class );
+
+        Map<String, Driver> drivers = tstExpectDriverLocatorFor( locator, 
+    		new String[] { driverId1, driverId2 }, 
+    		new int[] { 30, 3 } );
+
+        Driver noMatcher = tstCreateDriver( notMatchingButLoadedDriverId, 100 );
+
+        Device device = tstCreateDevice( new String[]{ "org.apache.felix" } );
+
+        final CountDownLatch attachLatch = tstExpectAttach( drivers.get( driverId1 ), device );
+
+        final CountDownLatch unloadDriverLatch = tstExpectUnloadDriverBundle( drivers.get ( driverId2 ) );
+
+        m_manager.locatorAdded( locator );
+
+        m_manager.driverAdded( m_osgi.getReference( noMatcher ), noMatcher );
+
+        m_manager.deviceAdded( m_osgi.getReference( device ), device );
+
+        if ( !attachLatch.await( 5, TimeUnit.SECONDS ) )
+        {
+            Assert.fail( "expected an attach" );
+        }
+        
+        //since driver1 is attached, we expect an uninstall()
+        //of all other (dynamically loaded) driver bundles
+        if ( !unloadDriverLatch.await( 5, TimeUnit.SECONDS ) )
+        {
+            Assert.fail( "expected an unload" );
+        }
+
+    }
+
+    @Test
+    public void DeviceAddedWithADriverLocatorUnloadFails() throws Exception
+    {
+
+        final String driverId1 = "org.apache.felix.driver-1.0";
+        final String driverId2 = "org.apache.felix.driver-1.1";
+        final String notMatchingButLoadedDriverId = "dotorg.apache.felix.driver-1.0";
+
+
+        DriverLocator locator = Mockito.mock( DriverLocator.class );
+
+        Map<String, Driver> drivers = tstExpectDriverLocatorFor( locator, 
+    		new String[] { driverId1, driverId2 }, 
+    		new int[] { 30, 3 } );
+
+        Driver noMatcher = tstCreateDriver( notMatchingButLoadedDriverId, 100 );
+
+        Device device = tstCreateDevice( new String[]{ "org.apache.felix" } );
+
+        final CountDownLatch attachLatch = tstExpectAttach( drivers.get( driverId1 ), device );
+
+        final CountDownLatch unloadDriverLatch = new CountDownLatch( 1 );
+        
+        ServiceReference driver2Ref = m_osgi.getReference( drivers.get( driverId2 ) );
+        Bundle driver2Bundle = m_osgi.getBundle( driver2Ref );
+        
+        Answer<Object> answer = new Answer<Object>() {
+        	
+        	public Object answer(InvocationOnMock invocation) throws Throwable {
+        		try {
+        			throw new BundleException("test driverBundle uninstall failed");
+        		}
+        		finally {
+        			unloadDriverLatch.countDown();
+        		}
+        	}
+        };
+        
+        Mockito.doAnswer(answer).when(driver2Bundle).uninstall();
+        
+        m_manager.locatorAdded( locator );
+
+        m_manager.driverAdded( m_osgi.getReference( noMatcher ), noMatcher );
+
+        m_manager.deviceAdded( m_osgi.getReference( device ), device );
+
+        if ( !attachLatch.await( 5, TimeUnit.SECONDS ) )
+        {
+            Assert.fail( "expected an attach" );
+        }
+        
+        if ( !unloadDriverLatch.await( 5, TimeUnit.SECONDS ) )
+        {
+            Assert.fail( "expected an unload" );
+        }
+
+        
+        //since driver1 is attached, we expect an uninstall()
+        //of all other (dynamically loaded) driver bundles
+        //Driver driver = drivers.get( driverId2 );
+        //tstVerifyBundleUninstall( driver );
+    }
+
+    /**
+     * Two drivers equally match the device. There is a driver selector
+     * that comes to the rescue that selects driver2. 
+     * 
+     * @throws Exception
+     */
+    @Test
+    public void EqualMatchWithDriverSelector() throws Exception
+    {
+
+        final String driverId1 = "org.apache.felix.driver-1.0";
+        final String driverId2 = "org.apache.felix.driver-1.1";
+
+        DriverLocator locator = Mockito.mock( DriverLocator.class );
+
+        Map<String, Driver> drivers = tstExpectDriverLocatorFor( locator, 
+    		new String[] { driverId1, driverId2 }, 
+    		new int[] { 20, 20 } );
+
+        Device device = tstCreateDevice( new String[]{ "org.apache.felix" } );
+
+        DriverSelector selector = Mockito.mock( DriverSelector.class );
+
+        SelectorMatcher matcher = new SelectorMatcher( driverId2 );
+
+        Mockito.when( selector.select( 
+        		Mockito.eq( m_osgi.getReference( device ) ), 
+        		Mockito.isA(Match[].class) ) ).thenAnswer( matcher );
+
+        final CountDownLatch attachLatch = tstExpectAttach( drivers.get( driverId2 ), device );
+
+
+        Utils.inject( m_manager, DriverSelector.class, selector );
+
+        m_manager.locatorAdded( locator );
+
+        m_manager.deviceAdded( m_osgi.getReference( device ), device );
+
+        if ( !attachLatch.await( 5, TimeUnit.SECONDS ) )
+        {
+            Assert.fail( "expected an attach" );
+        }
+        
+        
+        //driver2 is attached, so driver1 bundle should uninstall.
+        //Driver driver = drivers.get( driverId1 );
+        //tstVerifyBundleUninstall( driver );
+
+    }
+
+
+    //exceptional flow
+    @Test
+    public void DriverLocator_findDriverFails() throws Exception
+    {
+
+        final CountDownLatch latch = new CountDownLatch( 1 );
+
+        Answer<String[]> answer = new Answer<String[]>()
+        {
+
+            public String[] answer(InvocationOnMock invocation) throws Throwable
+            {
+                latch.countDown();
+                throw new RuntimeException( "test exception" );
+            }
+        };
+
+        DriverLocator locator = Mockito.mock( DriverLocator.class, "locator" );
+        Mockito.when( locator.findDrivers( Mockito.isA( Dictionary.class ) ) )
+        	.thenAnswer( answer );
+
+        Device device = tstCreateDevice( new String[]
+            { "org.apache.felix" } );
+
+        final CountDownLatch latch2 = new CountDownLatch( 1 );
+
+        Answer<Object> answer2 = new Answer<Object>()
+        {
+            public Object answer(InvocationOnMock invocation) throws Throwable
+            {
+                latch2.countDown();
+                return null;
+            }
+        };
+        
+        Mockito.doAnswer(answer2).when(device).noDriverFound();
+        
+
+        m_manager.locatorAdded( locator );
+        m_manager.deviceAdded( m_osgi.getReference( device ), device );
+
+        if ( !latch.await( 5, TimeUnit.SECONDS ) )
+        {
+            Assert.fail( "expected a call to DriverLocator.findDrivers" );
+        }
+
+        if ( !latch2.await( 5, TimeUnit.SECONDS ) )
+        {
+            Assert.fail( "expected a call to Driver.noDriverFound" );
+        }
+
+    }
+
+
+    /**
+     * This test verified correct behavior when after a driver
+     * attach led to a referral, this referral leads to an exception.
+     * 
+     * 
+     * @throws Exception
+     */
+    @Ignore
+    public void DriverReferral_ReferralFails() throws Exception
+    {
+
+        final String referredDriver = "org.apache.felix.driver-2.0";
+
+        String[] driverIds = new String[]
+            { "org.apache.felix.driver-1.0", "org.apache.felix.driver-1.1" };
+        
+        int[] driverMatches = new int[]{ 1, Device.MATCH_NONE };
+        
+        DriverLocator locator = Mockito.mock( DriverLocator.class, "locator for v1.x" );
+        Map<String, Driver> drivers = tstExpectDriverLocatorFor( locator, driverIds, driverMatches );
+
+        
+        DriverLocator locatorv2 = Mockito.mock( DriverLocator.class, "locator for v2.x (fails always)" );
+        Mockito.when( locatorv2.findDrivers( Mockito.isA( Dictionary.class ) ) )
+        	.thenReturn( null );
+
+        Mockito.when( locatorv2.loadDriver( Mockito.startsWith( "org.apache.felix.driver-1" ) ) )
+    		.thenReturn( null );
+        
+        InputStream referredInputStream = Mockito.mock(InputStream.class);
+        Mockito.when( locatorv2.loadDriver( referredDriver ) ).thenReturn( referredInputStream );
+
+
+        //this is what initial driver referral eventually leads
+        //to: the loading of a driver bundle
+        //we fake it, so that it fails
+        Mockito.when( m_context.installBundle( 
+        		Mockito.anyString(), 
+        		Mockito.isA( InputStream.class ) ) )
+        	.thenThrow(new BundleException( "test exception" ) );
+
+        Driver matched = drivers.get( "org.apache.felix.driver-1.0" );
+
+        final CountDownLatch latch = new CountDownLatch( 1 );
+
+        Answer<String> driver10_attach = new Answer<String>()
+        {
+            public String answer(InvocationOnMock invocation) throws Throwable
+            {
+            	System.out.println("driver10_attach()");
+                latch.countDown();
+                return referredDriver;
+            }
+        };
+
+        Device device = tstCreateDevice( new String[]{ "org.apache.felix" } );
+        
+
+        Mockito.when( matched.match( m_osgi.getReference( device ) ) ).thenReturn( 10 );
+
+        Mockito.when( matched.attach( Mockito.isA( ServiceReference.class ) ) )
+        	.thenAnswer( driver10_attach );
+
+//        for ( String driverId : driverIds )
+//        {
+//            Driver driver = drivers.get( driverId );
+//            tstExpectBundleUninstall( driver );
+//        }
+
+
+        //the actual test
+        
+        m_manager.locatorAdded( locator );
+        m_manager.locatorAdded( locatorv2 );
+        
+        //depman induced callback
+        m_manager.deviceAdded( m_osgi.getReference( device ), device );
+
+        
+        if ( !latch.await( 5, TimeUnit.SECONDS ) )
+        {
+            Assert.fail( "expected an attach to: " + driverIds[0] );
+        }
+
+        
+        Mockito.verify(device).noDriverFound();
+    }
+
+    /**
+     * @author dennisg
+     *
+     */
+    private class MatchAnswer implements Answer<Integer>
+    {
+
+        private final ServiceReference m_driverRef;
+
+        public MatchAnswer( ServiceReference driverRef )
+        {
+            m_driverRef = driverRef;
+        }
+
+
+        public Integer answer(InvocationOnMock invocation) throws Throwable
+        {
+            ServiceReference deviceRef = ( ServiceReference ) invocation.getArguments()[0];
+            String[] categories = String[].class.cast( deviceRef.getProperty( Constants.DEVICE_CATEGORY ) );
+            String driverId = String.class.cast( m_driverRef.getProperty( Constants.DRIVER_ID ) );
+
+            for ( String string : categories )
+            {
+                if ( driverId.startsWith( string ) )
+                {
+                    Object match = m_driverRef.getProperty( "match" );
+                    return Integer.valueOf( match.toString() );
+                }
+            }
+            return Device.MATCH_NONE;
+        }
+
+    }
+        
+
+    private class SelectorMatcher implements Answer<Integer>
+    {
+
+        private String m_driverId;
+
+
+        public SelectorMatcher( String driverId )
+        {
+            m_driverId = driverId;
+        }
+
+		public Integer answer(InvocationOnMock invocation) throws Throwable
+        {
+            int i = 0;
+            Match[] matches = (Match[])invocation.getArguments()[1];
+            
+            for ( Match match : matches )
+            {
+                if ( match.getDriver().getProperty( Constants.DRIVER_ID ).equals( m_driverId ) )
+                {
+                    return i;
+                }
+                i++;
+            }
+            return DriverSelector.SELECT_NONE;
+        }
+
+
+    }
+    
+}
diff --git a/deviceaccess/src/test/java/org/apache/felix/das/DriverAttributesTest.java b/deviceaccess/src/test/java/org/apache/felix/das/DriverAttributesTest.java
new file mode 100644
index 0000000..56cef12
--- /dev/null
+++ b/deviceaccess/src/test/java/org/apache/felix/das/DriverAttributesTest.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.das;
+
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.device.Device;
+import org.osgi.service.device.Driver;
+
+/**
+ * 
+ * Some simple tests for the DriverAttributes class.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ *
+ */
+public class DriverAttributesTest {
+
+	
+	private DriverAttributes m_attributes;
+	
+	@Mock
+	private ServiceReference m_ref;
+	
+	@Mock
+	private Driver m_driver;
+	
+	@Mock
+	private Bundle m_bundle;
+	
+	@Before
+	public void setUp() throws Exception {
+		
+		MockitoAnnotations.initMocks(this);
+		
+		Mockito.when(m_ref.getBundle()).thenReturn(m_bundle);
+		
+		Mockito.when(m_bundle.getLocation()).thenReturn("_DD_test-driverbundle");
+		
+		m_attributes = new DriverAttributes(m_ref, m_driver);
+	}
+
+
+	@Test
+	public void VerifyDriverReferenceReturned() throws Exception {
+		
+		Assert.assertEquals(m_ref, m_attributes.getReference());
+	}
+
+	@Test
+	public void VerifyDriverInUseByDevice() throws Exception {
+		
+		ServiceReference ref = Mockito.mock(ServiceReference.class);
+		
+		Mockito.when(ref.getProperty(Constants.OBJECTCLASS))
+			.thenReturn(new String[]{Object.class.getName()});
+		
+		Mockito.when(ref.getProperty(
+			org.osgi.service.device.Constants.DEVICE_CATEGORY))
+			.thenReturn(new String[]{"dummy"});
+		
+		Mockito.when(m_bundle.getServicesInUse()).thenReturn(new ServiceReference[]{ref});
+		
+		m_attributes.tryUninstall();
+		
+		Mockito.verify(m_bundle).getLocation();
+		Mockito.verify(m_bundle).getServicesInUse();
+		Mockito.verifyNoMoreInteractions(m_bundle);
+
+	}
+	
+	@Test
+	public void VerifyDriverInUseByDeviceInstance() throws Exception {
+		
+		ServiceReference ref = Mockito.mock(ServiceReference.class);
+		
+		Mockito.when(ref.getProperty(Constants.OBJECTCLASS)).thenReturn(new String[]{Device.class.getName()});
+		Mockito.when(ref.getProperty(
+				org.osgi.service.device.Constants.DEVICE_CATEGORY))
+				.thenReturn(new String[]{"dummy"});
+		
+		Mockito.when(m_bundle.getServicesInUse()).thenReturn(new ServiceReference[]{ref});
+		
+		m_attributes.tryUninstall();
+		
+		Mockito.verify(m_bundle).getLocation();
+		Mockito.verify(m_bundle).getServicesInUse();
+		Mockito.verifyNoMoreInteractions(m_bundle);
+
+	}
+	
+	
+	@Test
+	public void VerifyDriverInUseByNoDevice() throws Exception {
+		
+		ServiceReference ref = Mockito.mock(ServiceReference.class);
+		
+		Mockito.when(ref.getProperty(Constants.OBJECTCLASS)).thenReturn(new String[]{Object.class.getName()});
+		Mockito.when(m_bundle.getServicesInUse()).thenReturn(new ServiceReference[]{ref});
+		
+		m_attributes.tryUninstall();
+		
+		Mockito.verify(m_bundle).getLocation();
+		Mockito.verify(m_bundle).getServicesInUse();
+		Mockito.verify(m_bundle).uninstall();
+
+	}
+	@Test
+	public void VerifyDriverNotInUseLeadsToUnInstall1() throws Exception {
+		
+		Mockito.when(m_bundle.getServicesInUse()).thenReturn(new ServiceReference[0]);
+		
+		m_attributes.tryUninstall();
+		
+		Mockito.verify(m_bundle).uninstall();
+		
+
+	}
+	
+	@Test
+	public void VerifyDriverNotInUseLeadsToUnInstall2() throws Exception {
+		
+		m_attributes.tryUninstall();
+		
+		Mockito.verify(m_bundle).uninstall();
+		
+	}	
+	
+	@Test
+	public void VerifyAttachCalledOnDriver() throws Exception {
+		
+		
+		ServiceReference ref = Mockito.mock(ServiceReference.class);
+		m_attributes.attach(ref);
+		
+		Mockito.verify(m_driver).attach(Mockito.eq(ref));
+		
+	}
+
+	@Test
+	public void VerifyMatchCalledOnDriver() throws Exception {
+		
+		
+		ServiceReference ref = Mockito.mock(ServiceReference.class);
+		m_attributes.match(ref);
+		
+		Mockito.verify(m_driver).match(Mockito.eq(ref));
+		
+	}
+}
diff --git a/deviceaccess/src/test/java/org/apache/felix/das/OSGiMock.java b/deviceaccess/src/test/java/org/apache/felix/das/OSGiMock.java
new file mode 100644
index 0000000..c0acf3e
--- /dev/null
+++ b/deviceaccess/src/test/java/org/apache/felix/das/OSGiMock.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.das;
+
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+
+/**
+ * 
+ * a very simple mock of an osgi framework. enables the registration of services.
+ * automatically generates mocked service references for them.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class OSGiMock
+{
+
+	@Mock
+    private BundleContext m_context;
+
+    private Map<Object, ServiceReference> m_references;
+
+    private Map<ServiceReference, Bundle> m_bundles;
+
+    private int m_serviceIndex = 1;
+
+    public OSGiMock()
+    {
+    	MockitoAnnotations.initMocks(this);
+        m_references = new HashMap<Object, ServiceReference>();
+        m_bundles = new HashMap<ServiceReference, Bundle>();
+    }
+
+    public static ServiceReference createReference(final Properties p) 
+    {
+        ServiceReference ref = Mockito.mock( ServiceReference.class );
+
+        Mockito.when(ref.getProperty(Mockito.anyString())).thenAnswer(new Answer<Object>() {
+        	public Object answer(InvocationOnMock invocation) throws Throwable {
+        		return p.get(invocation.getArguments()[0].toString());
+        	}
+        });
+        
+        Mockito.when(ref.getPropertyKeys()).thenAnswer(new Answer<Object>() {
+        	public Object answer(InvocationOnMock invocation) throws Throwable {
+        		return p.keySet().toArray(new String[0]);
+        	}
+        });
+        
+        
+        return ref;
+    }
+
+
+
+    public BundleContext getBundleContext()
+    {
+        return m_context;
+    }
+
+
+    @SuppressWarnings("all")
+    public ServiceReference registerService( String[] ifaces, Object impl, Properties props )
+    {
+
+        ServiceReference ref = createReference( ifaces, props );
+
+        Mockito.when( m_context.registerService( ifaces, impl, props ) )
+        	.thenReturn( null );
+
+        Mockito.when( m_context.getService( ref ) ).thenReturn( impl );
+
+        m_references.put( impl, ref );
+
+        return ref;
+    }
+
+
+    public ServiceReference getReference( Object service )
+    {
+        return m_references.get( service );
+    }
+
+
+    public Bundle getBundle( ServiceReference ref )
+    {
+        return m_bundles.get( ref );
+    }
+
+
+
+    @SuppressWarnings("all")
+    public ServiceReference createReference( String[] ifaces, Properties props )
+    {
+
+        final ServiceReference ref = Mockito.mock( ServiceReference.class );
+
+        RefPropAnswer answer = new RefPropAnswer( props, ifaces );
+
+        Mockito.when( ref.getProperty( Mockito.anyString() ) )
+        	.thenAnswer( answer );
+
+        Mockito.when( ref.getPropertyKeys() )
+        	.thenReturn( props.keySet().toArray( new String[0] ) );
+
+        Bundle bundle = Mockito.mock( Bundle.class );
+        
+        Mockito.when( ref.getBundle() ).thenReturn( bundle );
+
+        m_bundles.put( ref, bundle );
+
+        return ref;
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    private class RefPropAnswer implements Answer<Object>
+    {
+        private final Dictionary m_p;
+
+
+        public RefPropAnswer( Dictionary p, String[] iface )
+        {
+            m_p = p;
+            m_p.put( Constants.OBJECTCLASS, iface );
+            m_p.put( Constants.SERVICE_ID, m_serviceIndex++ );
+        }
+
+
+        public Object answer(InvocationOnMock invocation) throws Throwable
+        {
+        	String key = (String)invocation.getArguments()[0];
+            return m_p.get( key );
+        }
+
+    }
+}
diff --git a/deviceaccess/src/test/java/org/apache/felix/das/Utils.java b/deviceaccess/src/test/java/org/apache/felix/das/Utils.java
new file mode 100644
index 0000000..9398e13
--- /dev/null
+++ b/deviceaccess/src/test/java/org/apache/felix/das/Utils.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.das;
+
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+
+/**
+ * Utility class for injecting objects and invoking
+ * methods that are normally invoked by the dependency manager.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ *
+ */
+public class Utils
+{
+
+    public static void invoke( Object target, String method )
+    {
+        try
+        {
+            Method m = target.getClass().getDeclaredMethod( method, new Class[0] );
+            m.setAccessible( true );
+            m.invoke( target, new Object[0] );
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+            junit.framework.Assert.fail( e.getMessage() );
+        }
+    }
+
+
+    public static void inject( Object target, Class<?> clazz, Object injectable )
+    {
+
+        Field[] fields = target.getClass().getDeclaredFields();
+
+        for ( Field field : fields )
+        {
+            if ( clazz == field.getType() )
+            {
+                field.setAccessible( true );
+                try
+                {
+                    field.set( target, injectable );
+                }
+                catch ( IllegalArgumentException e )
+                {
+                    e.printStackTrace();
+                }
+                catch ( IllegalAccessException e )
+                {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+}
diff --git a/deviceaccess/src/test/java/org/apache/felix/das/util/DriverAnalyzerTest.java b/deviceaccess/src/test/java/org/apache/felix/das/util/DriverAnalyzerTest.java
new file mode 100644
index 0000000..e44c37e
--- /dev/null
+++ b/deviceaccess/src/test/java/org/apache/felix/das/util/DriverAnalyzerTest.java
@@ -0,0 +1,113 @@
+package org.apache.felix.das.util;
+
+
+import java.util.Properties;
+
+import org.apache.felix.das.OSGiMock;
+import org.apache.felix.das.Utils;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.device.Constants;
+import org.osgi.service.device.Driver;
+import org.osgi.service.log.LogService;
+
+
+/**
+ * 
+ * Tests the Driver Analyzer.
+ * 
+ * Nothing fancy is being tested, but if something is changed this
+ * validates that at least the most basic feedback can be expected. 
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ *
+ */
+public class DriverAnalyzerTest {
+
+	
+	
+	private DriverAnalyzer m_analyzer;
+	
+	
+	@Mock
+	private LogService m_log;
+	
+	private OSGiMock m_osgi;
+	
+	@Before
+	public void setUp() throws Exception {
+		
+		MockitoAnnotations.initMocks(this);
+		
+		m_osgi = new OSGiMock();
+		m_analyzer = new DriverAnalyzer();
+
+		Utils.inject(m_analyzer, LogService.class, m_log);
+	}
+	
+	
+	@Test
+	public void VerifyCorrectDriverIsIgnored() {
+		
+		
+		Properties p = new Properties();
+		p.put(Constants.DRIVER_ID, "a-driver-id");
+		
+		
+		ServiceReference ref = m_osgi.createReference(new String[]{Driver.class.getName()}, p); 
+		
+		m_analyzer.driverAdded(ref);
+		
+		Mockito.verifyZeroInteractions(m_log);
+		
+	}
+
+	@Test
+	public void VerifyIncorrectDriverNoDriverId() {
+		
+		
+		Properties p = new Properties();
+		
+		ServiceReference ref = m_osgi.createReference(new String[]{Driver.class.getName()}, p); 
+		
+		m_analyzer.driverAdded(ref);
+		
+		Mockito.verify(m_log).log(Mockito.eq(LogService.LOG_ERROR), Mockito.anyString());
+		Mockito.verifyNoMoreInteractions(m_log);
+		
+	}
+	
+	@Test
+	public void VerifyIncorrectDriverInvalidDriverId() {
+		
+		Properties p = new Properties();
+		p.put(Constants.DRIVER_ID, new Object());
+
+		ServiceReference ref = m_osgi.createReference(new String[]{Driver.class.getName()}, p); 
+		
+		m_analyzer.driverAdded(ref);
+		
+		Mockito.verify(m_log).log(Mockito.eq(LogService.LOG_ERROR), Mockito.anyString());
+		Mockito.verifyNoMoreInteractions(m_log);
+		
+	}
+
+	@Test
+	public void VerifyIncorrectDriverEmptyDriverId() {
+		
+		Properties p = new Properties();
+		p.put(Constants.DRIVER_ID, "");
+
+		ServiceReference ref = m_osgi.createReference(new String[]{Driver.class.getName()}, p); 
+		
+		m_analyzer.driverAdded(ref);
+		
+		Mockito.verify(m_log).log(Mockito.eq(LogService.LOG_ERROR), Mockito.anyString());
+		Mockito.verifyNoMoreInteractions(m_log);
+		
+	}
+}
diff --git a/deviceaccess/src/test/java/org/apache/felix/das/util/DriverLoaderTest.java b/deviceaccess/src/test/java/org/apache/felix/das/util/DriverLoaderTest.java
new file mode 100644
index 0000000..789e2dd
--- /dev/null
+++ b/deviceaccess/src/test/java/org/apache/felix/das/util/DriverLoaderTest.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.das.util;
+
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.das.DeviceManager;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.device.Constants;
+import org.osgi.service.device.DriverLocator;
+
+
+/**
+ * The Device Manager delegates driver loading to the DriverLoader.
+ * This JUnit test tests the behavior of that DriverMatcher.
+ * 
+ * Tests all kinds of driver loading flows.
+ * all flows pertaining driver loading are grouped in the DriverLoader.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ *
+ */
+public class DriverLoaderTest
+{
+
+
+    private DriverLoader m_loader;
+
+    @Mock
+    private BundleContext m_context;
+
+    @Mock
+    private DeviceManager m_log;
+    
+    @Before
+    public void setUp() throws Exception
+    {
+    	
+    	MockitoAnnotations.initMocks(this);
+        m_loader = new DriverLoader( m_log, m_context );
+    }
+
+
+    private DriverLocator tstExpectDriverIdsFor(String[] ids) {
+    	
+        DriverLocator dl = Mockito.mock(DriverLocator.class );
+        Mockito.when( dl.findDrivers( Mockito.isA(Dictionary.class) ) ).thenReturn( ids );
+        return dl;
+    }
+    
+    /**
+     * test whether the driver loader can handle a situation where
+     * there are no DriverLocators.
+     * 
+     */
+    @Test
+    public void findDriversNoDriverLocators()
+    {
+
+        List<DriverLocator> locators = new ArrayList<DriverLocator>();
+
+
+        List<String> driverIds = m_loader.findDrivers( locators, new Properties() );
+        Assert.assertTrue( "should be an empty list", driverIds.size() == 0 );
+        
+    }
+
+
+    /**
+     * in this test there is a driver locator. the driver locator is instructed to 
+     * even return some driver ids.
+     * this test tests whether these driver ids are really returned. 
+     */
+    @Test
+    public void findDriversWithDriverLocator()
+    {
+
+        List<DriverLocator> locators = new ArrayList<DriverLocator>();
+
+        DriverLocator dl = tstExpectDriverIdsFor( 
+            new String[] { "org.apache.felix.driver-1.0", "org.apache.felix.driver-1.1" } );
+
+        locators.add( dl );
+
+        Properties dict = new Properties();
+        List<String> driverIds = m_loader.findDrivers( locators, dict );
+
+        Assert.assertEquals( "should not be an empty list", 2, driverIds.size());
+
+    }
+
+
+    /**
+     * in this test there are several driver locators, some of which return
+     * driver Ids, some don't. we expect an accurate number of driver ids being returned
+     * from the driverloader.
+     */
+    @Test
+    public void findDriversWithDriverLocators()
+    {
+
+        List<DriverLocator> locators = new ArrayList<DriverLocator>();
+
+        DriverLocator dl1 = tstExpectDriverIdsFor( 
+            new String[]{ "org.apache.felix.driver-1.0", "org.apache.felix.driver-1.1" } );
+        locators.add( dl1 );
+        
+        DriverLocator dl2 = tstExpectDriverIdsFor( 
+            new String[]{ "org.apache.felix.driver-1.2", "org.apache.felix.driver-1.3" } );
+        locators.add( dl2 );
+        
+        DriverLocator dl3 = tstExpectDriverIdsFor( null );
+        locators.add( dl3 );
+
+        
+        Properties dict = new Properties();
+        List<String> driverIds = m_loader.findDrivers( locators, dict );
+
+        Assert.assertEquals( "should not be an empty list", 4, driverIds.size() );
+
+    }
+
+
+    @Test
+    public void findDriversWithDriverLocatorFails()
+    {
+
+        Properties dict = new Properties();
+        List<DriverLocator> locators = new ArrayList<DriverLocator>();
+
+        DriverLocator dl = Mockito.mock( DriverLocator.class, "dl" );
+        locators.add( dl );
+
+        Mockito.when( dl.findDrivers( Mockito.eq( dict ) ) ).thenThrow( new RuntimeException( "test exception" ) );
+
+        List<String> driverIds = m_loader.findDrivers( locators, dict );
+
+        Assert.assertTrue( "should be an empty list", driverIds.size() == 0 );
+
+    }
+
+
+    @Test
+    public void loadDrivers() throws IOException, BundleException
+    {
+
+        List<DriverLocator> locators = new ArrayList<DriverLocator>();
+
+        DriverLocator dl = Mockito.mock( DriverLocator.class, "dl" );
+        locators.add( dl );
+
+        String[] driverIds = new String[]
+            { "org.apache.felix.driver-1.0", "org.apache.felix.driver-1.1", };
+
+        for ( String string : driverIds )
+        {
+            Mockito.when( dl.loadDriver( Mockito.eq( string ) ) ).thenReturn( null );
+            Bundle bundle = Mockito.mock( Bundle.class );
+            
+            Mockito.when( m_context.installBundle( "_DD_" + string, null ) ).thenReturn( bundle );
+            bundle.start();
+            
+            ServiceReference ref = Mockito.mock( ServiceReference.class );
+            Mockito.when( ref.getProperty( Constants.DRIVER_ID ) ).thenReturn( string );
+            Mockito.when( bundle.getRegisteredServices() ).thenReturn( new ServiceReference[]
+                { ref } );
+        }
+
+        List<ServiceReference> refs = m_loader.loadDrivers( locators, driverIds );
+
+        Assert.assertEquals( "", 2, refs.size() );
+        for ( ServiceReference serviceReference : refs )
+        {
+            String driverId = "" + serviceReference.getProperty( Constants.DRIVER_ID );
+            if ( !driverId.equals( driverIds[0] ) && !driverId.equals( driverIds[1] ) )
+            {
+                Assert.fail( "unexpected driverId" );
+            }
+        }
+
+    }
+
+
+    @Test
+    public void loadDrivers_LoadFails() throws IOException, BundleException
+    {
+
+        List<DriverLocator> locators = new ArrayList<DriverLocator>();
+
+        DriverLocator dl = Mockito.mock( DriverLocator.class, "dl" );
+        locators.add( dl );
+
+        String[] driverIds = new String[]
+            { "org.apache.felix.driver-1.0", "org.apache.felix.driver-1.1", };
+
+        for ( String string : driverIds )
+        {
+            Mockito.when( dl.loadDriver( string ) ).thenThrow( new IOException( "test exception" ) );
+        }
+
+        List<ServiceReference> refs = m_loader.loadDrivers( locators, driverIds );
+
+        Assert.assertEquals( "", 0, refs.size() );
+
+    }
+
+
+    @Test
+    public void loadDrivers_InstallFails() throws IOException, BundleException
+    {
+
+        List<DriverLocator> locators = new ArrayList<DriverLocator>();
+
+        DriverLocator dl = Mockito.mock( DriverLocator.class, "dl" );
+        locators.add( dl );
+
+        String[] driverIds = new String[]
+            { "org.apache.felix.driver-1.0", "org.apache.felix.driver-1.1", };
+
+        for ( String string : driverIds )
+        {
+        	Mockito.when( dl.loadDriver( string ) ).thenReturn( null );
+        	Mockito.when( m_context.installBundle( DriverLoader.DRIVER_LOCATION_PREFIX + string, null ) )
+        		.thenThrow(new BundleException( "test exception" ) );
+        }
+
+        List<ServiceReference> refs = m_loader.loadDrivers( locators, driverIds );
+
+        Assert.assertEquals( "", 0, refs.size() );
+    }
+
+}
diff --git a/deviceaccess/src/test/java/org/apache/felix/das/util/DriverMatcherTest.java b/deviceaccess/src/test/java/org/apache/felix/das/util/DriverMatcherTest.java
new file mode 100644
index 0000000..c020d7e
--- /dev/null
+++ b/deviceaccess/src/test/java/org/apache/felix/das/util/DriverMatcherTest.java
@@ -0,0 +1,329 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.das.util;
+
+
+
+import org.apache.felix.das.DriverAttributes;
+import org.apache.felix.das.DeviceManager;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.device.Driver;
+import org.osgi.service.device.DriverSelector;
+import org.osgi.service.device.Match;
+
+
+/**
+ * The Device Manager delegates driver matching to the DriverMatcher.
+ * This JUnit test tests the behavior of that DriverMatcher.
+ * 
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DriverMatcherTest
+{
+
+    private DriverMatcher m_matcherImpl;
+
+    private int m_serviceId;
+
+    @Mock
+    private DeviceManager m_log;
+
+    @Before
+    public void setUp() throws Exception
+    {
+
+        m_serviceId = 0;
+
+        MockitoAnnotations.initMocks(this);
+    	
+        m_matcherImpl = new DriverMatcher( m_log );
+
+    }
+
+
+    private String tstDriverId( Match match )
+    {
+        return ( String ) match.getDriver().getProperty( org.osgi.service.device.Constants.DRIVER_ID );
+    }
+
+
+    private DriverAttributes tstCreateDriverAttributes( String id, int match, int ranking ) throws Exception
+    {
+
+        Bundle bundle = Mockito.mock( Bundle.class );
+        ServiceReference ref = Mockito.mock( ServiceReference.class );
+        
+        
+        Mockito.when(ref.getBundle()).thenReturn(bundle);
+        Mockito.when(bundle.getLocation()).thenReturn(DriverLoader.DRIVER_LOCATION_PREFIX + "-" + id);
+        
+        Mockito.when(ref.getProperty(Constants.SERVICE_ID))
+        	.thenReturn(m_serviceId++);
+        
+        Mockito.when(ref.getProperty(org.osgi.service.device.Constants.DRIVER_ID))
+        	.thenReturn(id);
+        
+        
+        
+        if ( ranking > 0 )
+        {
+        	Mockito.when( ref.getProperty( Constants.SERVICE_RANKING ) ).thenReturn( ranking );
+        }
+        else if ( ranking == 0 )
+        {
+        	Mockito.when( ref.getProperty( Constants.SERVICE_RANKING ) ).thenReturn( null );
+        }
+        else
+        {
+            //an invalid ranking object
+        	Mockito.when( ref.getProperty( Constants.SERVICE_RANKING ) ).thenReturn( new Object() );
+        }
+
+        Driver driver = Mockito.mock( Driver.class );
+        Mockito.when( driver.match( Mockito.isA( ServiceReference.class ) ) ).thenReturn( match );
+
+        return new DriverAttributes( ref, driver );
+
+    }
+
+
+    private void add( String id, int match ) throws Exception
+    {
+        add( id, match, 0 );
+    }
+
+
+    private void add( String id, int match, int ranking ) throws Exception
+    {
+        m_matcherImpl.add( match, tstCreateDriverAttributes( id, match, ranking ) );
+    }
+
+
+    @Test
+    public void GetBestMatchWithNoDriver() throws Exception
+    {
+
+        Match match = m_matcherImpl.getBestMatch();
+        Assert.assertNull( match );
+
+    }
+
+
+    @Test
+    public void GetBestMatchWithOneDriver() throws Exception
+    {
+
+        add( "org.apache.felix.driver-1.0", 1 );
+
+        Match match = m_matcherImpl.getBestMatch();
+        Assert.assertNotNull( match );
+        Assert.assertEquals( "org.apache.felix.driver-1.0", tstDriverId( match ) );
+
+    }
+
+    
+    @Test
+    public void GetSelectBestMatchThrowsException() throws Exception
+    {
+    	
+    	ServiceReference deviceRef = Mockito.mock(ServiceReference.class);
+    	DriverSelector selector = Mockito.mock(DriverSelector.class);
+
+    	Mockito.when(selector.select(Mockito.eq(deviceRef), Mockito.isA(Match[].class)))
+    		.thenThrow(new IllegalArgumentException("test"));
+    	
+        Match match = m_matcherImpl.selectBestMatch(deviceRef, selector);
+        Assert.assertNull( match );
+
+    }
+
+    @Test
+    public void GetBestMatchWithMultipleDrivers() throws Exception
+    {
+
+        add( "org.apache.felix.driver.a-1.0", 1 );
+        add( "org.apache.felix.driver.b-1.0", 1 );
+        add( "org.apache.felix.driver.c-1.0", 10 );
+
+        Match match = m_matcherImpl.getBestMatch();
+        Assert.assertNotNull( match );
+        Assert.assertEquals( "org.apache.felix.driver.c-1.0", tstDriverId( match ) );
+
+    }
+
+
+    @Test
+    public void GetBestMatchWithInvalidRanking() throws Exception
+    {
+
+        add( "org.apache.felix.driver.a-1.0", 1, 0 );
+        add( "org.apache.felix.driver.b-1.0", 1, -1 );
+
+        Match match = m_matcherImpl.getBestMatch();
+        Assert.assertNotNull( match );
+        Assert.assertEquals( "org.apache.felix.driver.a-1.0", tstDriverId( match ) );
+
+    }
+
+
+    @Test
+    public void GetBestMatchWithSameRanking() throws Exception
+    {
+
+        add( "org.apache.felix.driver.a-1.0", 1 );
+        add( "org.apache.felix.driver.b-1.0", 1 );
+
+        Match match = m_matcherImpl.getBestMatch();
+        Assert.assertNotNull( match );
+        Assert.assertEquals( "org.apache.felix.driver.a-1.0", tstDriverId( match ) );
+        Assert.assertEquals( 1, match.getMatchValue() );
+    }
+
+
+    @Test
+    public void GetBestMatchWithDifferentRanking() throws Exception
+    {
+
+        add( "org.apache.felix.driver.a-1.0", 1, 2 );
+        add( "org.apache.felix.driver.b-1.0", 1 );
+
+        Match match = m_matcherImpl.getBestMatch();
+
+        Assert.assertNotNull( match );
+        final String driverId = "org.apache.felix.driver.a-1.0";
+
+        Assert.assertEquals( driverId, tstDriverId( match ) );
+        Assert.assertEquals( 1, match.getMatchValue() );
+    }
+
+
+    @Test
+    public void GetBestMatchWithDifferentMatchValue() throws Exception
+    {
+
+        add( "org.apache.felix.driver.a-1.0", 1 );
+        add( "org.apache.felix.driver.b-1.0", 2 );
+        add( "org.apache.felix.driver.c-1.0", 1 );
+
+        Match match = m_matcherImpl.getBestMatch();
+        Assert.assertNotNull( match );
+        Assert.assertEquals( "org.apache.felix.driver.b-1.0", tstDriverId( match ) );
+
+        Assert.assertEquals( 2, match.getMatchValue() );
+    }
+
+
+    @Test
+    public void selectBestDriver() throws Exception
+    {
+
+        DriverSelector selector = Mockito.mock( DriverSelector.class );
+        ServiceReference deviceRef = Mockito.mock( ServiceReference.class );
+
+        add( "org.apache.felix.driver-1.0", 1 );
+        add( "org.apache.felix.driver-1.1", 1 );
+        add( "org.apache.felix.driver-1.2", 1 );
+        add( "org.apache.felix.driver-1.3", 1 );
+        add( "org.apache.felix.driver-1.4", 1 );
+        add( "org.apache.felix.driver-1.5", 1 );
+        
+        
+        
+        //this is the actual driverselector implementation
+        Mockito.when( selector.select( Mockito.isA(ServiceReference.class), Mockito.isA(Match[].class) ) )
+        	.thenAnswer( new Answer<Integer>()
+        {
+        	
+        	public Integer answer(InvocationOnMock invocation) throws Throwable
+            {
+                Match[] matches = ( Match[] ) invocation.getArguments()[1];
+                int index = 0;
+                for ( Match m : matches )
+                {
+                    if ( tstDriverId( m ).endsWith( "1.3" ) )
+                    {
+                        return index;
+                    }
+                    index++;
+                }
+                Assert.fail( "expected unreachable" );
+                return null;
+            }
+        } );
+
+
+        Match match = m_matcherImpl.selectBestMatch( deviceRef, selector );
+
+        Assert.assertNotNull( "no match returned", match );
+        String driverId = tstDriverId( match );
+
+        Assert.assertEquals( "org.apache.felix.driver-1.3", driverId );
+    }
+
+
+    @Test
+    public void selectFails() throws Exception
+    {
+
+        DriverSelector selector = Mockito.mock( DriverSelector.class );
+        ServiceReference deviceRef = Mockito.mock( ServiceReference.class );
+
+        Mockito.when( selector.select( Mockito.eq( deviceRef ), Mockito.isA(Match[].class) ) )
+            .thenThrow( new RuntimeException( "test exception" ) );
+
+        add( "org.apache.felix.driver-1.5", 1 );
+
+        Match match = m_matcherImpl.selectBestMatch( deviceRef, selector );
+
+        Assert.assertNull( match );
+
+    }
+    
+    
+    @Test
+    public void VerifyMatchToString() throws Exception
+    {
+
+        DriverSelector selector = Mockito.mock( DriverSelector.class );
+        ServiceReference deviceRef = Mockito.mock( ServiceReference.class );
+
+        Mockito.when( selector.select( Mockito.eq( deviceRef ), Mockito.isA(Match[].class) ) )
+            .thenReturn( 0 );
+
+        add( "org.apache.felix.driver-1.5", 2 );
+
+        Match match = m_matcherImpl.selectBestMatch( deviceRef, selector );
+
+        Assert.assertNotNull( match );
+        Assert.assertNotNull( match.toString() );
+
+    }
+
+}
diff --git a/deviceaccess/src/test/java/org/apache/felix/das/util/UtilTest.java b/deviceaccess/src/test/java/org/apache/felix/das/util/UtilTest.java
new file mode 100644
index 0000000..c19a690
--- /dev/null
+++ b/deviceaccess/src/test/java/org/apache/felix/das/util/UtilTest.java
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.das.util;
+
+
+import java.util.Properties;
+
+import junit.framework.Assert;
+
+import org.apache.felix.das.Utils;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.device.Constants;
+import org.osgi.service.device.Device;
+import org.osgi.service.log.LogService;
+
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ *
+ */
+public class UtilTest
+{
+
+    private DeviceAnalyzer m_devA;
+
+    @Mock
+    private LogService m_log;
+
+    @Mock
+    private BundleContext m_context;
+
+
+    @Before
+    public void before() throws Exception
+    {
+
+    	MockitoAnnotations.initMocks(this);
+    	
+        m_devA = new DeviceAnalyzer( m_context );
+        Utils.inject( m_devA, LogService.class, m_log );
+        
+        
+        String f1 = "(objectClass=org.osgi.service.device.Device)";
+        Filter deviceFilter = FrameworkUtil.createFilter(f1);
+        Mockito.when(m_context.createFilter(Mockito.eq(f1))).thenReturn(deviceFilter);
+        
+        String f2 = "(DEVICE_CATEGORY=*)";
+        Filter driverFilter = FrameworkUtil.createFilter(f2);
+        Mockito.when(m_context.createFilter(f2)).thenReturn(driverFilter);
+        
+
+        Utils.invoke( m_devA, "start" );
+    }
+
+    
+    
+    private ServiceReference createReference(final Properties p) 
+    {
+        ServiceReference ref = Mockito.mock( ServiceReference.class );
+
+        Mockito.when(ref.getProperty(Mockito.anyString())).thenAnswer(new Answer<Object>() {
+        	public Object answer(InvocationOnMock invocation) throws Throwable {
+        		return p.get(invocation.getArguments()[0].toString());
+        	}
+        });
+        
+        Mockito.when(ref.getPropertyKeys()).thenAnswer(new Answer<Object>() {
+        	public Object answer(InvocationOnMock invocation) throws Throwable {
+        		return p.keySet().toArray(new String[0]);
+        	}
+        });
+        
+        
+        return ref;
+    }
+
+    @Test
+    public void ShowDeviceIfThereIsAnInvalidCategory() throws Exception
+    {
+
+        Properties p = new Properties();
+        p.put( org.osgi.framework.Constants.OBJECTCLASS, new String[]{Object.class.getName()} );
+        p.put(Constants.DEVICE_CATEGORY, "dummy");
+
+        ServiceReference ref = createReference(p);
+        
+        m_devA.deviceAdded( ref );
+        
+        Mockito.verify(m_log).log(Mockito.eq(LogService.LOG_ERROR), Mockito.anyString());
+
+    }
+
+
+    @Test
+    public void ShowDeviceIfThereIsNoCategory() throws Exception
+    {
+
+        Properties p = new Properties();
+        p.put( org.osgi.framework.Constants.OBJECTCLASS, new String[]{Object.class.getName()} );
+
+        ServiceReference ref = createReference(p);
+        
+        m_devA.deviceAdded( ref );
+        
+        Mockito.verify(m_log).log( Mockito.eq( LogService.LOG_ERROR ), Mockito.isA( String.class ) );
+    }
+
+    @Test 
+    public void VerifyValidIsDeviceInstanceValidationIfDevice() throws InvalidSyntaxException 
+    {
+
+        Properties p = new Properties();
+        p.put( org.osgi.framework.Constants.OBJECTCLASS, new String[]{Device.class.getName()} );
+        
+    	ServiceReference ref = createReference(p);
+    
+    	Assert.assertTrue( "Incorrectly determined as no device", Util.isDeviceInstance(ref) );
+    }
+
+    @Test 
+    public void VerifyValidIsDeviceInstanceValidationThrowsException() throws InvalidSyntaxException 
+    {
+
+        Properties p = new Properties();
+        p.put( org.osgi.framework.Constants.OBJECTCLASS, new String[]{Device.class.getName()} );
+        
+    	ServiceReference ref = createReference(p);
+    
+    	Assert.assertTrue( "Incorrectly determined as no device", Util.isDeviceInstance(ref) );
+    }
+
+    @Test 
+    public void VerifyValidFilterStringCreation() throws InvalidSyntaxException {
+    	
+    	Object[] data = new Object[]{"a","b","c","d"};
+    	String str = Util.createFilterString("(|(%s=%s)(%s=%s))", data);
+    	
+    	Assert.assertEquals("filter string mismatch","(|(a=b)(c=d))", str);
+    }
+
+    @Test 
+    public void VerifyValidFilterCreation() throws InvalidSyntaxException {
+    	
+    	Object[] data = new Object[]{Constants.DEVICE_CATEGORY, "dummy"};
+    	Filter filter = Util.createFilter("(%s=%s)", data);
+    	
+    	
+    	Properties matching = new Properties();
+    	matching.put(Constants.DEVICE_CATEGORY, new String[]{"dummy", "nonsense"});
+    	Assert.assertTrue("matching filter does not match", filter.match(matching));
+    	
+    	Properties notmatching = new Properties();
+    	notmatching.put(Constants.DEVICE_CATEGORY, new String[]{"lummy", "nonsense"});
+    	Assert.assertFalse("notmatching filter does match", filter.match(notmatching));
+
+    	
+    }
+    
+ 
+    
+    
+    
+    @Test
+    public void ShowDeviceIfThereIsAnEmptyCategory() throws Exception
+    {
+
+        Properties p = new Properties();
+        p.put( org.osgi.framework.Constants.OBJECTCLASS, new String[]{Object.class.getName()} );
+        p.put( Constants.DEVICE_CATEGORY, new String[0] );
+
+        
+        ServiceReference ref = createReference(p);
+
+        m_devA.deviceAdded( ref );
+
+        Mockito.verify(m_log).log( Mockito.eq( LogService.LOG_ERROR ), Mockito.isA( String.class ) );
+
+    }
+
+
+    @Test
+    public void NoShowDeviceIfThereIsAValidCategory() throws Exception
+    {
+
+        Properties p = new Properties();
+        p.put( org.osgi.framework.Constants.OBJECTCLASS, new String[]{Device.class.getName()} );
+        p.put( Constants.DEVICE_CATEGORY, new String[]{"dummy"} );
+
+        ServiceReference ref = createReference(p);
+
+        m_devA.deviceAdded( ref );
+    }
+}
