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 );
+    }
+}
