From 6a914dcbd1c89027eafae6021af4199a636e4e48 Mon Sep 17 00:00:00 2001
From: erik <erik@77661180-640e-0410-b3a8-9f9b13e6d0e0>
Date: Fri, 4 Apr 2008 22:06:16 +0000
Subject: [PATCH] some major refactoring. ServiceREgistry eliminated as well as
 Service and DefaultService. There is now a many-to-one relation from required
 to provided service which leads to a more natural design.

---
 .../org/wamblee/system/AbstractComponent.java |  51 ++----
 .../java/org/wamblee/system/Component.java    |   9 +-
 .../java/org/wamblee/system/Container.java    |  44 +++--
 .../DefaultProvidedInterfaceDescriptor.java   |  13 +-
 .../DefaultRequiredInterfaceDescriptor.java   |  69 +++++++-
 .../org/wamblee/system/DefaultService.java    |  48 ------
 .../system/DefaultServiceRegistry.java        |  45 -----
 .../org/wamblee/system/ProvidedInterface.java |  12 ++
 .../org/wamblee/system/RequiredInterface.java |  20 +++
 .../main/java/org/wamblee/system/Service.java |  27 ---
 .../org/wamblee/system/ServiceRegistry.java   |  12 --
 .../org/wamblee/system/SystemAssembler.java   |  41 ++---
 .../java/org/wamblee/system/Application.java  |  10 +-
 .../java/org/wamblee/system/Environment.java  |  15 +-
 .../wamblee/system/SystemAssemblerTest.java   | 154 +++++++++---------
 .../system/spring/RequiredServiceBean.java    |  16 +-
 .../system/spring/SpringComponent.java        | 113 ++++++-------
 .../system/spring/SpringComponentTest.java    |  62 +++----
 18 files changed, 368 insertions(+), 393 deletions(-)
 delete mode 100644 system/general/src/main/java/org/wamblee/system/DefaultService.java
 delete mode 100644 system/general/src/main/java/org/wamblee/system/DefaultServiceRegistry.java
 delete mode 100644 system/general/src/main/java/org/wamblee/system/Service.java
 delete mode 100644 system/general/src/main/java/org/wamblee/system/ServiceRegistry.java

diff --git a/system/general/src/main/java/org/wamblee/system/AbstractComponent.java b/system/general/src/main/java/org/wamblee/system/AbstractComponent.java
index a78b46f1..074e3ab0 100644
--- a/system/general/src/main/java/org/wamblee/system/AbstractComponent.java
+++ b/system/general/src/main/java/org/wamblee/system/AbstractComponent.java
@@ -2,14 +2,12 @@ package org.wamblee.system;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.wamblee.system.Component.Status;
 
 /**
  * Abstract subsystem class making it easy to implement new subsystems.
@@ -19,17 +17,14 @@ public abstract class AbstractComponent implements Component {
 	private static final Log LOG = LogFactory.getLog(AbstractComponent.class);
 
 	private Status _status; 
-	private String _name;
-	private ServiceRegistry _registry; 
+	private String _name; 
 	private List<ProvidedInterface> _provided;
 	private List<RequiredInterface> _required;
-	private Map<ProvidedInterface, Service> _running;
+	private Set<ProvidedInterface> _running;
 	
 	/**
 	 * Constructs the subsystem.
-	 * 
-	 * @param aRegistry
-	 *            Registry of services.
+	 *
 	 * @param aName
 	 *            Name of the system.
 	 * @param aProvided
@@ -37,16 +32,15 @@ public abstract class AbstractComponent implements Component {
 	 * @param aRequired
 	 *            Required services.
 	 */
-	protected AbstractComponent(String aName, ServiceRegistry aRegistry, ProvidedInterface[] aProvided,
+	protected AbstractComponent(String aName, ProvidedInterface[] aProvided,
 			RequiredInterface[] aRequired) {
 		_status = Status.NOT_STARTED;
 		_name = aName;
-		_registry = aRegistry; 
 		_provided = new ArrayList<ProvidedInterface>();
 		_provided.addAll(Arrays.asList(aProvided));
 		_required = new ArrayList<RequiredInterface>();
 		_required.addAll(Arrays.asList(aRequired));
-		_running = new HashMap<ProvidedInterface, Service>();
+		_running = new HashSet<ProvidedInterface>();
 	}
 	
 	@Override
@@ -58,10 +52,6 @@ public abstract class AbstractComponent implements Component {
 	public final String getName() {
 		return _name;
 	}
-	
-	public ServiceRegistry getRegistry() {
-		return _registry;
-	}
 
 	@Override
 	public final ProvidedInterface[] getProvidedServices() {
@@ -74,25 +64,17 @@ public abstract class AbstractComponent implements Component {
 	}
 
 	@Override
-	public final Service[] start(String aContext,
-			Service[] aRequiredServices) {
-		LOG.info("Initializing '" + aContext + "." + _name + "' with "
-				+ Arrays.asList(aRequiredServices));
-		doStart(aContext + "." + getName(), aRequiredServices);
+	public final void start(String aContext) {
+		LOG.info("Initializing '" + aContext + "." + _name + "'");
+		doStart(aContext + "." + getName());
 		_status = Status.RUNNING;
-		return _running.values().toArray(new Service[0]);
 	}
 
 	/**
 	 * Must be implemented for initializing the subsystem. The implementation
 	 * must call {@link #addService(Service)} for each service that is started.
-	 *  
-	 * @param aRequiredServices
-	 *            Services that are already running from other subsystems that
-	 *            may be used.
 	 */
-	protected abstract void doStart(String aContext,
-			Service[] aRequiredServices);
+	protected abstract void doStart(String aContext);
 
 	/**
 	 * Implementations must call this method to indicate that a new service has
@@ -104,21 +86,18 @@ public abstract class AbstractComponent implements Component {
 	protected final void addService(String aContext,
 			ProvidedInterface aDescriptor, Object aService) {
 		LOG.info(aContext + ": service '" + aService + "' started.");
-		Service svc = getRegistry().register(aDescriptor, aService);
-		_running.put(svc.getDescriptor(), svc);
+		_running.add(aDescriptor);
+		aDescriptor.publish(aService);
 	}
 
 	@Override
-	public Service[] getRunningServices() {
-		return _running.values().toArray(new Service[0]);
+	public ProvidedInterface[] getRunningServices() {
+		return _running.toArray(new ProvidedInterface[0]);
 	}
 	
 	@Override
 	public void stop() {
 		doStop(); 	
-		for (Service svc: _running.values()) { 
-			getRegistry().remove(svc);
-		}
 		_status = Status.STOPPED;
 	}
 	
diff --git a/system/general/src/main/java/org/wamblee/system/Component.java b/system/general/src/main/java/org/wamblee/system/Component.java
index e72dd7f0..4083c5bd 100644
--- a/system/general/src/main/java/org/wamblee/system/Component.java
+++ b/system/general/src/main/java/org/wamblee/system/Component.java
@@ -40,12 +40,9 @@ public interface Component {
 	/**
 	 * Initialises the subsytem by starting all the services that
 	 * it described as provided. 
-	 * @param aContext Unique name for the subsystem. 
-	 * @param aRequiredServices Running services from other 
-	 * subsystems that are required by this subsystem. 
-	 * @return Services that are running in the subsystem. 
+	 * @param aContext Unique name for the subsystem.  
 	 */
-	Service[] start(String aContext, Service[] aRequiredServices);
+	void start(String aContext);
 	
 	/**
 	 * Stops a subsystem. 
@@ -59,5 +56,5 @@ public interface Component {
 	 * {@link #initialize(String, Service[])} has been called. 
 	 * @return
 	 */
-	Service[] getRunningServices();
+	ProvidedInterface[] getRunningServices();
 }
diff --git a/system/general/src/main/java/org/wamblee/system/Container.java b/system/general/src/main/java/org/wamblee/system/Container.java
index a23a7373..d9dc29be 100644
--- a/system/general/src/main/java/org/wamblee/system/Container.java
+++ b/system/general/src/main/java/org/wamblee/system/Container.java
@@ -28,11 +28,11 @@ public class Container extends AbstractComponent {
 	 * @param aProvided Provided services of the system. 
 	 * @param aRequired Required services by the system. 
 	 */
-	public Container(String aName, ServiceRegistry aRegistry, Component[] aSystems,
+	public Container(String aName, Component[] aSystems,
 			ProvidedInterface[] aProvided, RequiredInterface[] aRequired) {
-		super(aName, aRegistry, aProvided, aRequired);
+		super(aName, aProvided, aRequired);
 		_systems = aSystems;
-		validate();
+		validate(aRequired);
 	}
 
 	/**
@@ -41,7 +41,7 @@ public class Container extends AbstractComponent {
 	 * no services in the provided list that cannot be provided. 
 	 * Also logs a warning in case of superfluous requirements.  
 	 */
-	private void validate() {
+	private void validate(RequiredInterface[] aRequired) {
 		List<ProvidedInterface> provided = new ArrayList<ProvidedInterface>();
 		for (Component system : _systems) {
 			provided.addAll(Arrays.asList(system.getProvidedServices()));
@@ -69,12 +69,17 @@ public class Container extends AbstractComponent {
 
 		List<RequiredInterface> reallyRequired = new ArrayList<RequiredInterface>(
 				required);
+		// Compute all required interfaces that are not provided
 		for (ProvidedInterface service : provided) {
-			reallyRequired.remove(service); 
-		}
-		for (RequiredInterface service: getRequiredServices()) { 
-			reallyRequired.remove(service); 
+			List<RequiredInterface> fulfilled = 
+				Arrays.asList(SystemAssembler.filterRequiredServices(service, 
+					reallyRequired));
+			reallyRequired.removeAll(fulfilled); 
 		}
+		// Now the remaining interfaces should be covered by the required
+		// list. 
+		reallyRequired.removeAll(Arrays.asList(aRequired));
+		
 		String missingRequired = "";
 		for (RequiredInterface service: reallyRequired) {
 			missingRequired += service + "\n";
@@ -85,14 +90,23 @@ public class Container extends AbstractComponent {
 	}
 
 	@Override
-	protected void doStart(String aContext, Service[] aRequiredServices) {
-		List<ProvidedInterface> descriptors = new ArrayList<ProvidedInterface>();
-		for (Service service : aRequiredServices) {
-			descriptors.add(service.getDescriptor());
+	protected void doStart(String aContext) {
+		List<ProvidedInterface> provided = new ArrayList<ProvidedInterface>();
+		
+		// all interfaces from the required list of this container are
+		// provided to the components inside it.
+		RequiredInterface[] required = getRequiredServices();
+		for (RequiredInterface intf: required) { 
+		    ProvidedInterface provider = intf.getProvider(); 
+		    if ( provider == null ) { 
+		    	throw new SystemAssemblyException(aContext + ": required interface '" + intf +"' is not provided");
+		    }
+			provided.add(intf.getProvider());
 		}
-		SystemAssembler assembler = new SystemAssembler(aContext + "." + getName(), _systems,
-				descriptors.toArray(new ProvidedInterface[0]));
-		assembler.start(getRegistry(), aRequiredServices);
+		
+		SystemAssembler assembler = new SystemAssembler( _systems, 
+				provided.toArray(new ProvidedInterface[0]));
+		assembler.start();
 	}
 	
 	@Override
diff --git a/system/general/src/main/java/org/wamblee/system/DefaultProvidedInterfaceDescriptor.java b/system/general/src/main/java/org/wamblee/system/DefaultProvidedInterfaceDescriptor.java
index 2b51c60a..3b38be7a 100644
--- a/system/general/src/main/java/org/wamblee/system/DefaultProvidedInterfaceDescriptor.java
+++ b/system/general/src/main/java/org/wamblee/system/DefaultProvidedInterfaceDescriptor.java
@@ -10,7 +10,8 @@ import java.util.Arrays;
 public class DefaultProvidedInterfaceDescriptor implements ProvidedInterface {
 	
 	private String _name; 
-	private Class[] _interfaces; 
+	private Class[] _interfaces;
+	private Object _implementation; 
 	
 	/**
 	 * Constructs the descriptor. 
@@ -36,6 +37,16 @@ public class DefaultProvidedInterfaceDescriptor implements ProvidedInterface {
 		return _interfaces;
 	}
 	
+	@Override
+	public void publish(Object aImplementation) {
+		_implementation = aImplementation; 	
+	}
+	
+	@Override
+	public Object getImplementation() {
+		return _implementation; 
+	}
+	
 	@Override
 	public boolean equals(Object obj) {
 		if ( !(obj instanceof DefaultProvidedInterfaceDescriptor)) { 
diff --git a/system/general/src/main/java/org/wamblee/system/DefaultRequiredInterfaceDescriptor.java b/system/general/src/main/java/org/wamblee/system/DefaultRequiredInterfaceDescriptor.java
index 9e434c08..580b390b 100644
--- a/system/general/src/main/java/org/wamblee/system/DefaultRequiredInterfaceDescriptor.java
+++ b/system/general/src/main/java/org/wamblee/system/DefaultRequiredInterfaceDescriptor.java
@@ -1,20 +1,31 @@
 package org.wamblee.system;
 
-public class DefaultRequiredInterfaceDescriptor extends DefaultProvidedInterfaceDescriptor
-		implements RequiredInterface {
+import java.util.Arrays;
 
+public class DefaultRequiredInterfaceDescriptor implements RequiredInterface {
+
+	private String _name;
+	private Class[] _required;
+	private ProvidedInterface _provider; 
+	
 	public DefaultRequiredInterfaceDescriptor(String aName, Class aInterface) {
-		super(aName, aInterface);
+		this(aName, new Class[] { aInterface }); 
 	}
 
 	public DefaultRequiredInterfaceDescriptor(String aName, Class[] aInterfaces) {
-		super(aName, aInterfaces);
+		_name = aName; 
+		_required = aInterfaces; 
 	}
 
+	@Override
+	public String getName() {
+		return _name;
+	}
+	
 	@Override
 	public boolean implementedBy(ProvidedInterface aDescriptor) {
 		Class[] provided = aDescriptor.getInterfaceTypes();
-		for (Class required : getInterfaceTypes()) {
+		for (Class required : _required) {
 			if ( !serviceProvided(required, provided)) { 
 				return false; 
 			}
@@ -40,5 +51,53 @@ public class DefaultRequiredInterfaceDescriptor extends DefaultProvidedInterface
 		}
 		return false; 
 	}
+	
+	@Override
+	public ProvidedInterface getProvider() {
+		return _provider; 
+	}
+	
+	@Override
+	public void setProvider(ProvidedInterface aProvider) {
+		_provider = aProvider; 	
+	}
+
+	@Override
+	public <T> T getImplementation(Class<T> aClass) {
+		return (T)_provider.getImplementation();
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if ( !(obj instanceof DefaultRequiredInterfaceDescriptor)) { 
+			return false; 
+		}
+		DefaultRequiredInterfaceDescriptor descr = (DefaultRequiredInterfaceDescriptor)obj;
+		if ( _required.length != descr._required.length ) { 
+			return false; 
+		}
+		String[] interfaces1 = new String[_required.length];
+		String[] interfaces2 = new String[_required.length];
+		for (int i = 0; i < _required.length; i++) {  
+			interfaces1[i] = _required[i].getName();
+			interfaces2[i] = descr._required[i].getName();
+		}
+		Arrays.sort(interfaces1);
+		Arrays.sort(interfaces2);
+		return Arrays.equals(interfaces1, interfaces2);
+	}
 
+	@Override
+	public int hashCode() {
+		return _required.hashCode(); 
+	}
+	
+	@Override
+	public String toString() {
+		StringBuffer buf = new StringBuffer();
+		for (Class intf: _required) { 
+			buf.append("." + intf.getName());
+		}
+		return buf.toString();
+	}
 }
diff --git a/system/general/src/main/java/org/wamblee/system/DefaultService.java b/system/general/src/main/java/org/wamblee/system/DefaultService.java
deleted file mode 100644
index a8a2692e..00000000
--- a/system/general/src/main/java/org/wamblee/system/DefaultService.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.wamblee.system;
-
-/**
- * Default service implementation.
- *
- * @author Erik Brakkee
- */
-public class DefaultService implements Service {
-
-	private String _id;
-	private ProvidedInterface _descriptor;
-	private Object _service;
-
-	/**
-	 * Constructs the service.
-	 * 
-	 * @param aDescriptor
-	 *            Descriptor to use.
-	 * @param aService
-	 *            Service.
-	 */
-	public DefaultService(String aId, ProvidedInterface aDescriptor,
-			Object aService) {
-		_id = aId;
-		_descriptor = aDescriptor;
-		_service = aService;
-	}
-
-	@Override
-	public String getId() {
-		return _id;
-	}
-
-	@Override
-	public ProvidedInterface getDescriptor() {
-		return _descriptor;
-	}
-
-	@Override
-	public <T> T reference(Class<T> aClass) {
-		return (T) _service;
-	}
-
-	@Override
-	public String toString() {
-		return "(" + _descriptor + ", " + _service + ")";
-	}
-}
diff --git a/system/general/src/main/java/org/wamblee/system/DefaultServiceRegistry.java b/system/general/src/main/java/org/wamblee/system/DefaultServiceRegistry.java
deleted file mode 100644
index 27d576e5..00000000
--- a/system/general/src/main/java/org/wamblee/system/DefaultServiceRegistry.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.wamblee.system;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-public class DefaultServiceRegistry implements ServiceRegistry {
-
-	private int _count;
-	private Map<String, Service> _services;
-
-	public DefaultServiceRegistry() {
-		_count = 0;
-		_services = new HashMap<String, Service>();
-	}
-
-	@Override
-	public synchronized Service register(ProvidedInterface aDescriptor,
-			Object aService) {
-		_count++;
-		String id = "" + _count;
-		Service svc = new DefaultService(id, aDescriptor, aService);
-		_services.put(id, svc);
-		return svc;
-	}
-	
-	@Override
-	public void remove(Service aService) {
-		Service svc = _services.remove(aService.getId());
-		if ( svc == null ) { 
-			throw new IllegalArgumentException("Service '" + aService.getId() + "' does not exist");
-		}
-	}
-
-	@Override
-	public synchronized Service find(String aId) {
-		return _services.get(aId);
-	}
-
-	@Override
-	public Service[] listAllServices() {
-		return new ArrayList<Service>(_services.values())
-				.toArray(new Service[0]);
-	}
-}
diff --git a/system/general/src/main/java/org/wamblee/system/ProvidedInterface.java b/system/general/src/main/java/org/wamblee/system/ProvidedInterface.java
index 11b56646..20976d8a 100644
--- a/system/general/src/main/java/org/wamblee/system/ProvidedInterface.java
+++ b/system/general/src/main/java/org/wamblee/system/ProvidedInterface.java
@@ -20,4 +20,16 @@ public interface ProvidedInterface {
 	 * @return Service type. 
 	 */
 	Class[] getInterfaceTypes();
+	
+	/**
+	 * Publish an implementation of the interface. 
+	 * @param aImplementation
+	 */
+	void publish(Object aImplementation); 
+	
+	/**
+	 * Gets the implementation. 
+	 * @return Implementation or null if not started. 
+	 */
+	Object getImplementation(); 
 }
diff --git a/system/general/src/main/java/org/wamblee/system/RequiredInterface.java b/system/general/src/main/java/org/wamblee/system/RequiredInterface.java
index fd607403..f012df51 100644
--- a/system/general/src/main/java/org/wamblee/system/RequiredInterface.java
+++ b/system/general/src/main/java/org/wamblee/system/RequiredInterface.java
@@ -13,4 +13,24 @@ public interface RequiredInterface {
 	 * @return
 	 */
 	boolean implementedBy(ProvidedInterface aInterface);
+	
+	/**
+	 * Sets the provider of this interface. 
+	 * @param aProvider Provider. 
+	 */
+	void setProvider(ProvidedInterface aProvider);
+	
+	/**
+	 * Getst the provider interface. 
+	 * @return Provider or null if not set. 
+	 */
+	ProvidedInterface getProvider(); 
+	
+	/**
+	 * Gets the implementation of the required interface. 
+	 * @param <T>
+	 * @param aClass Interface type. 
+	 * @return Interface implementation or null if not known yet. 
+	 */
+	<T> T getImplementation(Class<T> aClass); 
 }
diff --git a/system/general/src/main/java/org/wamblee/system/Service.java b/system/general/src/main/java/org/wamblee/system/Service.java
deleted file mode 100644
index 8624c0cc..00000000
--- a/system/general/src/main/java/org/wamblee/system/Service.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.wamblee.system;
-
-/**
- * Represents a running service.
- *
- * @author Erik Brakkee
- */
-public interface Service {
-	
-	/**
-	 * Gets the ide of the service in the registry. 
-	 * @return Service id. 
-	 */
-	String getId(); 
-	
-	/**
-	 * Gets the descriptor of the service. 
-	 * @return Descriptor. 
-	 */
-	ProvidedInterface getDescriptor(); 
-	
-	/**
-	 * Returns a reference to the running service. 
-	 * @return Service. 
-	 */
-	<T> T reference(Class<T> aClass);
-}
diff --git a/system/general/src/main/java/org/wamblee/system/ServiceRegistry.java b/system/general/src/main/java/org/wamblee/system/ServiceRegistry.java
deleted file mode 100644
index 7fe35063..00000000
--- a/system/general/src/main/java/org/wamblee/system/ServiceRegistry.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.wamblee.system;
-
-public interface ServiceRegistry {
-
-	Service register(ProvidedInterface aDescriptor, Object aService);
-	
-	void remove(Service aService); 
-	
-	Service find(String aId); 
-	
-	Service[] listAllServices(); 
-}
diff --git a/system/general/src/main/java/org/wamblee/system/SystemAssembler.java b/system/general/src/main/java/org/wamblee/system/SystemAssembler.java
index 5cdb3890..50e0e3ab 100644
--- a/system/general/src/main/java/org/wamblee/system/SystemAssembler.java
+++ b/system/general/src/main/java/org/wamblee/system/SystemAssembler.java
@@ -4,8 +4,10 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -23,6 +25,7 @@ public class SystemAssembler {
 	private static final String ROOT_CONTEXT_NAME = "root";
 	private String _context;
 	private Component[] _systems;
+	private ProvidedInterface[] _required; 
 
 	public static RequiredInterface[] filterRequiredServices(
 			ProvidedInterface aProvided,
@@ -77,18 +80,19 @@ public class SystemAssembler {
 			ProvidedInterface[] aAvailableServices) {
 		_context = aContext;
 		_systems = aSystems;
-		validate(aAvailableServices);
+		_required = aAvailableServices; 
+		validate();
 	}
 
 	/**
 	 * Determines if the systems are ordered appropriately so that all
 	 * dependencies are met.
 	 */
-	private void validate(ProvidedInterface[] aDescriptors)
+	private void validate()
 			throws SystemAssemblyException {
 
 		List<ProvidedInterface> allProvided = new ArrayList<ProvidedInterface>();
-		for (ProvidedInterface descriptor : aDescriptors) {
+		for (ProvidedInterface descriptor : _required) {
 			allProvided.add(descriptor);
 		}
 		for (Component system : _systems) {
@@ -128,39 +132,36 @@ public class SystemAssembler {
 	/**
 	 * Starts the subsystems.
 	 * 
-	 * @param aRegistry
-	 *            Service registry to which created services must be registered.
 	 * @param aRequiredServices
 	 *            Services that are available from other systems that have been
 	 *            started before.
 	 */
-	public void start(ServiceRegistry aRegistry, Service[] aRequiredServices) {
+	public void start() {
 		LOG.info("Starting '" + _context + "'");
-		Map<ProvidedInterface, Service> allProvided = new HashMap<ProvidedInterface, Service>();
-
-		for (Service service : aRequiredServices) {
-			allProvided.put(service.getDescriptor(), service);
-		}
+		Set<ProvidedInterface> allProvided = new HashSet<ProvidedInterface>();
+		allProvided.addAll(Arrays.asList(_required));
+		
 		for (Component system : _systems) {
 			
 			// Compose a list of the required services required for the subsystem.
 			
 			RequiredInterface[] descriptors = system
 					.getRequiredServices();
-			List<Service> services = new ArrayList<Service>();
-			for (RequiredInterface descriptor : descriptors) {
+			List<ProvidedInterface> services = new ArrayList<ProvidedInterface>();
+			for (RequiredInterface required : descriptors) {
 				ProvidedInterface[] provided = filterProvidedServices(
-						descriptor, allProvided.keySet());
-				services.add(allProvided.get(provided[0]));
+						required, allProvided);
+				assert provided.length == 1; 	
+				services.add(provided[0]);
+				required.setProvider(provided[0]);
 			}
 			
 			// Start the service. 
-			Service[] provided = system.start(_context, services
-					.toArray(new Service[0]));
+			system.start(_context);
 			
-			// Add started services to the map of started services.
-			for (Service service : provided) {
-				allProvided.put(service.getDescriptor(), service);
+			// Add started services to the set of started services.
+			for (ProvidedInterface service : system.getProvidedServices()) {
+				allProvided.add(service);
 			}
 
 		}
diff --git a/system/general/src/test/java/org/wamblee/system/Application.java b/system/general/src/test/java/org/wamblee/system/Application.java
index 3825c989..b84ca5e2 100644
--- a/system/general/src/test/java/org/wamblee/system/Application.java
+++ b/system/general/src/test/java/org/wamblee/system/Application.java
@@ -3,18 +3,20 @@ package org.wamblee.system;
 import javax.sql.DataSource;
 
 public class Application extends AbstractComponent {
-	private static final RequiredInterface[] REQUIRED = 
+	private static RequiredInterface[] required() {
+		return
 		new RequiredInterface[] { 
     			new DefaultRequiredInterfaceDescriptor("datasource", DataSource.class), 
     			new DefaultRequiredInterfaceDescriptor("integer", Integer.class)
     	};
+	}
 	
-	public Application(ServiceRegistry aRegistry) {
-		super("application", aRegistry, new ProvidedInterface[0], REQUIRED); 
+	public Application() {
+		super("application", new ProvidedInterface[0], required()); 
 	}
 
 	@Override
-	protected void doStart(String aContext, Service[] aRequiredServices) {
+	protected void doStart(String aContext) {
 		// Empty, no services provided externally. 
 	}
 	
diff --git a/system/general/src/test/java/org/wamblee/system/Environment.java b/system/general/src/test/java/org/wamblee/system/Environment.java
index e2bd2b80..27537e0a 100644
--- a/system/general/src/test/java/org/wamblee/system/Environment.java
+++ b/system/general/src/test/java/org/wamblee/system/Environment.java
@@ -5,20 +5,21 @@ import javax.sql.DataSource;
 
 public class Environment extends AbstractComponent {
 	
-	private static final ProvidedInterface[] PROVIDED = 
-		new ProvidedInterface[] { 
+	private static final ProvidedInterface[] provided() { 
+		return new ProvidedInterface[] { 
     			new DefaultProvidedInterfaceDescriptor("datasource", DataSource.class), 
     			new DefaultProvidedInterfaceDescriptor("integer", Integer.class)
     	};
+	}
 	
-	public Environment(ServiceRegistry aRegistry) { 
-		super("environment", aRegistry, PROVIDED, new RequiredInterface[0]);
+	public Environment() { 
+		super("environment", provided(), new RequiredInterface[0]);
 	}
 	
 	@Override
-	protected void doStart(String aContext, Service[] aRequiredServices) {
-	    addService(aContext, PROVIDED[0], new Integer(1));
-	    addService(aContext, PROVIDED[1], new Integer(2));
+	protected void doStart(String aContext) {
+	    addService(aContext, getProvidedServices()[0], new Integer(1));
+	    addService(aContext, getProvidedServices()[1], new Integer(2));
 	}
 	
 	@Override
diff --git a/system/general/src/test/java/org/wamblee/system/SystemAssemblerTest.java b/system/general/src/test/java/org/wamblee/system/SystemAssemblerTest.java
index c372bf04..9412caee 100644
--- a/system/general/src/test/java/org/wamblee/system/SystemAssemblerTest.java
+++ b/system/general/src/test/java/org/wamblee/system/SystemAssemblerTest.java
@@ -11,12 +11,9 @@ import junit.framework.TestCase;
 
 public class SystemAssemblerTest extends TestCase {
 
-	private ServiceRegistry _registry;
-
 	@Override
 	protected void setUp() throws Exception {
 		super.setUp();
-		_registry = new DefaultServiceRegistry();
 	}
 
 	private static class MyMultiple implements Serializable, Runnable {
@@ -27,10 +24,10 @@ public class SystemAssemblerTest extends TestCase {
 	}
 
 	public void testFilterProvided() {
-		RequiredInterface req1 = new DefaultRequiredInterfaceDescriptor(
-				"name", Runnable.class);
-		RequiredInterface req2 = new DefaultRequiredInterfaceDescriptor(
-				"name", Serializable.class);
+		RequiredInterface req1 = new DefaultRequiredInterfaceDescriptor("name",
+				Runnable.class);
+		RequiredInterface req2 = new DefaultRequiredInterfaceDescriptor("name",
+				Serializable.class);
 		ProvidedInterface prov1 = new DefaultProvidedInterfaceDescriptor(
 				"name", Runnable.class);
 		ProvidedInterface prov2 = new DefaultProvidedInterfaceDescriptor(
@@ -42,54 +39,46 @@ public class SystemAssemblerTest extends TestCase {
 				SystemAssembler.filterRequiredServices(prov1, Arrays
 						.asList(new RequiredInterface[] { req1 })));
 		AssertionUtils.assertEquals(new RequiredInterface[] { req1 },
-				SystemAssembler.filterRequiredServices(prov1,
-						Arrays.asList(new RequiredInterface[] { req1,
-								req2 })));
-		AssertionUtils.assertEquals(new RequiredInterface[] { req1,
-				req2 }, SystemAssembler.filterRequiredServices(prov3, Arrays
-				.asList(new RequiredInterface[] { req1, req2 })));
-
-		AssertionUtils.assertEquals(
-				new ProvidedInterface[] { prov1 },
+				SystemAssembler.filterRequiredServices(prov1, Arrays
+						.asList(new RequiredInterface[] { req1, req2 })));
+		AssertionUtils.assertEquals(new RequiredInterface[] { req1, req2 },
+				SystemAssembler.filterRequiredServices(prov3, Arrays
+						.asList(new RequiredInterface[] { req1, req2 })));
+
+		AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 },
 				SystemAssembler.filterProvidedServices(req1, Arrays
 						.asList(new ProvidedInterface[] { prov1 })));
-		AssertionUtils.assertEquals(
-				new ProvidedInterface[] { prov1 }, SystemAssembler
-						.filterProvidedServices(req1, Arrays
-								.asList(new ProvidedInterface[] {
-										prov1, prov2 })));
-		AssertionUtils.assertEquals(new ProvidedInterface[] { prov1,
-				prov3 }, SystemAssembler.filterProvidedServices(req1, Arrays
-				.asList(new ProvidedInterface[] { prov1, prov3 })));
+		AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 },
+				SystemAssembler.filterProvidedServices(req1, Arrays
+						.asList(new ProvidedInterface[] { prov1, prov2 })));
+		AssertionUtils.assertEquals(new ProvidedInterface[] { prov1, prov3 },
+				SystemAssembler.filterProvidedServices(req1, Arrays
+						.asList(new ProvidedInterface[] { prov1, prov3 })));
 	}
 
 	public void testEnvironmentApplication() {
-		Component environment = new Environment(_registry);
-		Component application = new Application(_registry);
+		Component environment = new Environment();
+		Component application = new Application();
 		SystemAssembler assembler = new SystemAssembler(new Component[] {
 				environment, application }, new ProvidedInterface[0]);
-		assembler.start(_registry, new Service[0]);
-		Service[] envServices = environment.getRunningServices();
+		assembler.start();
+		ProvidedInterface[] envServices = environment.getRunningServices();
 		assertEquals(2, envServices.length);
-		Service[] appServices = environment.getRunningServices();
+		ProvidedInterface[] appServices = environment.getRunningServices();
 		assertEquals(2, appServices.length);
-		assertEquals(2, _registry.listAllServices().length);
 
+		// TODO test stopping!!!!!!
 		environment.stop();
-		assertEquals(0, _registry.listAllServices().length);
-
 		application.stop();
-		assertEquals(0, _registry.listAllServices().length);
 	}
 
 	public void testApplicationEnvironment() {
 		try {
-			Component environment = new Environment(_registry);
-			Component application = new Application(_registry);
+			Component environment = new Environment();
+			Component application = new Application();
 			SystemAssembler assembler = new SystemAssembler(new Component[] {
-					application, environment },
-					new ProvidedInterface[0]);
-			assembler.start(_registry, new Service[0]);
+					application, environment }, new ProvidedInterface[0]);
+			assembler.start();
 		} catch (SystemAssemblyException e) {
 			// e.printStackTrace();
 			return;
@@ -98,15 +87,15 @@ public class SystemAssemblerTest extends TestCase {
 	}
 
 	public void testComposite() {
-		Component environment = new Environment(_registry);
-		Component application = new Application(_registry);
+		Component environment = new Environment();
+		Component application = new Application();
 		assertEquals(Status.NOT_STARTED, environment.getStatus());
 		assertEquals(Status.NOT_STARTED, application.getStatus());
-		Container system = new Container("all", _registry, new Component[] {
-				environment, application }, new ProvidedInterface[0],
+		Container system = new Container("all", new Component[] { environment,
+				application }, new ProvidedInterface[0],
 				new RequiredInterface[0]);
 		assertEquals(Status.NOT_STARTED, system.getStatus());
-		system.start("root", new Service[0]);
+		system.start("root");
 		RequiredInterface[] required = system.getRequiredServices();
 		assertEquals(0, required.length);
 		ProvidedInterface[] provided = system.getProvidedServices();
@@ -123,11 +112,10 @@ public class SystemAssemblerTest extends TestCase {
 
 	public void testCompositeWithWrongProvidedInfo() {
 		try {
-			Component environment = new Environment(_registry);
-			Component application = new Application(_registry);
+			Component environment = new Environment();
+			Component application = new Application();
 			Container system = new Container(
 					"all",
-					_registry,
 					new Component[] { environment, application },
 					new ProvidedInterface[] { new DefaultProvidedInterfaceDescriptor(
 							"string", String.class) },
@@ -138,17 +126,35 @@ public class SystemAssemblerTest extends TestCase {
 		fail();
 	}
 
+	public void testCompositeRequiredInterfaceNotProvided() {
+		try {
+			Component environment = new Environment();
+			Component application = new Application();
+			Container system = new Container(
+					"all",
+					new Component[] { environment, application },
+					new ProvidedInterface[0],
+					new RequiredInterface[] { new DefaultRequiredInterfaceDescriptor(
+							"string", String.class) });
+			system.start("root");
+		} catch (SystemAssemblyException e) {
+			return;
+		}
+		fail();
+	}
+
 	public void testCompositeWithSuperfluousRequiredInfo() {
-		Component environment = new Environment(_registry);
-		Component application = new Application(_registry);
+		Component environment = new Environment();
+		Component application = new Application();
 		Container system = new Container(
 				"all",
-				_registry,
 				new Component[] { environment, application },
 				new ProvidedInterface[0],
 				new RequiredInterface[] { new DefaultRequiredInterfaceDescriptor(
 						"string", String.class) });
-		system.start("root", new Service[0]);
+		system.getRequiredServices()[0].setProvider(
+				new DefaultProvidedInterfaceDescriptor("hallo", String.class));
+		system.start("root");
 		RequiredInterface[] required = system.getRequiredServices();
 		assertEquals(1, required.length);
 		ProvidedInterface[] provided = system.getProvidedServices();
@@ -157,13 +163,12 @@ public class SystemAssemblerTest extends TestCase {
 
 	public void testCompositeWithExternalDependencesNotProvided() {
 		try {
-			Component environment = new Environment(_registry);
-			Component application = new Application(_registry);
-			Container system = new Container("all", _registry,
-					new Component[] { application },
-					new ProvidedInterface[0], application
-							.getRequiredServices());
-			system.start("root", new Service[0]);
+			Component environment = new Environment();
+			Component application = new Application();
+			Container system = new Container("all",
+					new Component[] { application }, new ProvidedInterface[0],
+					application.getRequiredServices());
+			system.start("root");
 		} catch (SystemAssemblyException e) {
 			return;
 		}
@@ -173,14 +178,16 @@ public class SystemAssemblerTest extends TestCase {
 
 	public void testCompositeWithExternalDependencesProvided() {
 
-		Component environment = new Environment(_registry);
-		Component application = new Application(_registry);
-		Container system = new Container("all", _registry,
-				new Component[] { application },
-				new ProvidedInterface[0], application
-						.getRequiredServices());
-		Service[] envServices = environment.start("env", new Service[0]);
-		system.start("root", envServices);
+		Component environment = new Environment();
+		Component application = new Application();
+		Container system = new Container("all",
+				new Component[] { application }, new ProvidedInterface[0],
+				application.getRequiredServices());
+		environment.start("env");
+		system.getRequiredServices()[0].setProvider(environment.getProvidedServices()[0]);
+		system.getRequiredServices()[1].setProvider(environment.getProvidedServices()[1]);
+		
+		system.start("root");
 		RequiredInterface[] required = system.getRequiredServices();
 		assertEquals(2, required.length);
 		ProvidedInterface[] provided = system.getProvidedServices();
@@ -190,13 +197,13 @@ public class SystemAssemblerTest extends TestCase {
 
 	public void testAmbiguousInterfaces() {
 		try {
-			Component environment1 = new Environment(_registry);
-			Component environment2 = new Environment(_registry);
-			Component application = new Application(_registry);
+			Component environment1 = new Environment();
+			Component environment2 = new Environment();
+			Component application = new Application();
 			SystemAssembler assembler = new SystemAssembler(new Component[] {
 					environment1, environment2, application },
 					new ProvidedInterface[0]);
-			assembler.start(_registry, new Service[0]);
+			assembler.start();
 
 		} catch (SystemAssemblyException e) {
 			return;
@@ -206,12 +213,11 @@ public class SystemAssemblerTest extends TestCase {
 
 	public void testIncompleteRequirements() {
 		try {
-			Component application = new Application(_registry);
-			Container system = new Container("all", _registry,
-					new Component[] { application },
-					new ProvidedInterface[0],
+			Component application = new Application();
+			Container system = new Container("all",
+					new Component[] { application }, new ProvidedInterface[0],
 					new RequiredInterface[0]);
-			system.start("root", new Service[0]);
+			system.start("root");
 		} catch (SystemAssemblyException e) {
 			return;
 		}
diff --git a/system/spring/src/main/java/org/wamblee/system/spring/RequiredServiceBean.java b/system/spring/src/main/java/org/wamblee/system/spring/RequiredServiceBean.java
index eaf55336..50e7e967 100644
--- a/system/spring/src/main/java/org/wamblee/system/spring/RequiredServiceBean.java
+++ b/system/spring/src/main/java/org/wamblee/system/spring/RequiredServiceBean.java
@@ -1,6 +1,9 @@
 package org.wamblee.system.spring;
 
 import org.springframework.beans.factory.FactoryBean;
+import org.wamblee.system.ProvidedInterface;
+import org.wamblee.system.RequiredInterface;
+import org.wamblee.system.SystemAssemblyException;
 
 /**
  * Bean which adds a service required by the spring component to 
@@ -10,19 +13,26 @@ import org.springframework.beans.factory.FactoryBean;
  */
 class RequiredServiceBean implements FactoryBean {
 	
-	private String _id;
+	private RequiredInterface _required; 
 	
 	/**
 	 * Constructs the bean. 
 	 * @param aId Id of the bean in the service registry.  
 	 */
 	public RequiredServiceBean(String aId) { 
-		_id = aId; 
+		RequiredInterface[] required = SpringComponent.THIS.get().getRequiredServices();
+		for ( RequiredInterface intf: required) { 
+			if ( intf.getName().equals(aId)) { 
+				_required = intf; 
+				return;
+			}
+		}
+		throw new SystemAssemblyException("Cannot resolve provided component '" + aId + "'");
 	}
 
 	@Override
 	public Object getObject() throws Exception {
-		return SpringComponent.REGISTRY.get().find(_id).reference(Object.class);
+		return _required.getImplementation(Object.class);
 	}
 
 	@Override
diff --git a/system/spring/src/main/java/org/wamblee/system/spring/SpringComponent.java b/system/spring/src/main/java/org/wamblee/system/spring/SpringComponent.java
index b9a2648c..0b0921e6 100644
--- a/system/spring/src/main/java/org/wamblee/system/spring/SpringComponent.java
+++ b/system/spring/src/main/java/org/wamblee/system/spring/SpringComponent.java
@@ -14,25 +14,20 @@ import org.wamblee.system.AbstractComponent;
 import org.wamblee.system.ProvidedInterface;
 import org.wamblee.system.RequiredInterface;
 import org.wamblee.system.Service;
-import org.wamblee.system.ServiceRegistry;
 import org.wamblee.system.SystemAssembler;
 import org.wamblee.system.SystemAssemblyException;
 
 /**
- * Represents a system configured based on spring.
- * The spring config files that are configured should not contain any PropertyPlaceholderConfigurer 
- * objects. 
- *
+ * Represents a system configured based on spring. The spring config files that
+ * are configured should not contain any PropertyPlaceholderConfigurer objects.
+ * 
  * @author Erik Brakkee
  */
 public class SpringComponent extends AbstractComponent {
 
-	/**
-	 * Singleton access to the service registry. Required while starting up.
-	 */
-	static ThreadLocal<ServiceRegistry> REGISTRY = new ThreadLocal<ServiceRegistry>();
+	static final ThreadLocal<SpringComponent> THIS = new ThreadLocal<SpringComponent>();
 
-	private Properties _properties; 
+	private Properties _properties;
 	private String[] _configFiles;
 	private Map<String, ProvidedInterface> _provided;
 	private Map<RequiredInterface, String> _required;
@@ -62,57 +57,59 @@ public class SpringComponent extends AbstractComponent {
 	 *            names that the spring config files use for each required
 	 *            service.
 	 */
-	public SpringComponent(String aName, ServiceRegistry aRegistry, String[] aConfigFiles,
+	public SpringComponent(String aName, String[] aConfigFiles,
 			Map<String, ProvidedInterface> aProvided,
 			Map<RequiredInterface, String> aRequired) {
-		super(aName, aRegistry, aProvided.values().toArray(new ProvidedInterface[0]),
+		super(aName, aProvided.values().toArray(new ProvidedInterface[0]),
 				aRequired.keySet().toArray(new RequiredInterface[0]));
-		_properties = new Properties(); 
+		_properties = new Properties();
 		_configFiles = aConfigFiles;
 		_provided = aProvided;
 		_required = aRequired;
 	}
-	
+
 	/**
-	 * Must be called to make a property available in the application context. 
-	 * @param aKey Property key. 
-	 * @param aValue Property value. 
+	 * Must be called to make a property available in the application context.
+	 * 
+	 * @param aKey
+	 *            Property key.
+	 * @param aValue
+	 *            Property value.
 	 */
-	public void setProperty(String aKey, String aValue) { 
+	public void setProperty(String aKey, String aValue) {
 		_properties.put(aKey, aValue);
 	}
-	
-	public void addProperties(Properties aProperties) { 
-		for (Object key: aProperties.keySet()) { 
-			setProperty((String)key, aProperties.getProperty((String)key));
+
+	public void addProperties(Properties aProperties) {
+		for (Object key : aProperties.keySet()) {
+			setProperty((String) key, aProperties.getProperty((String) key));
 		}
 	}
 
 	@Override
-	protected void doStart(String aContext, 
-			Service[] aRequiredServices) {
-		ServiceRegistry oldRegistry = REGISTRY.get();
-		try {	
-			REGISTRY.set(getRegistry());
-			try {
-				_parentContext = new GenericApplicationContext();
-
-				registerRequiredServices(aRequiredServices);
-				
-				_parentContext.refresh();
-
-				parseConfigFiles();
-				
-				_context.addBeanFactoryPostProcessor(new PropertySetter(_properties));
-				_context.refresh(); 
-
-				exposeProvidedServices(aContext);
-			} catch (Exception e) {
-				throw new SystemAssemblyException(
-						"Failed to assemble spring system", e);
-			}
+	protected void doStart(String aContext) {
+
+		SpringComponent old = THIS.get();
+		THIS.set(this);
+		try {
+			_parentContext = new GenericApplicationContext();
+
+			registerRequiredServices();
+
+			_parentContext.refresh();
+
+			parseConfigFiles();
+
+			_context
+					.addBeanFactoryPostProcessor(new PropertySetter(_properties));
+			_context.refresh();
+
+			exposeProvidedServices(aContext);
+		} catch (Exception e) {
+			throw new SystemAssemblyException(
+					"Failed to assemble spring system", e);
 		} finally {
-			REGISTRY.set(oldRegistry);
+			THIS.set(old);
 		}
 	}
 
@@ -136,27 +133,21 @@ public class SpringComponent extends AbstractComponent {
 				_parentContext);
 	}
 
-	private void registerRequiredServices(Service[] aRequiredServices) {
+	private void registerRequiredServices() {
 		// Register required services in a parent context
-
-		for (Service svc: aRequiredServices) { 
-			String id = svc.getId();
-			ProvidedInterface descriptor = svc.getDescriptor();
-			RequiredInterface[] requiredServices = SystemAssembler.filterRequiredServices(descriptor,
-					_required.keySet()); 
-			for (RequiredInterface required: requiredServices) { 
-				String beanName = _required.get(required);
-				ConstructorArgumentValues cargs = new ConstructorArgumentValues();
-				cargs.addGenericArgumentValue(id); 
-				BeanDefinition definition = new RootBeanDefinition(RequiredServiceBean.class, cargs,
-						new MutablePropertyValues());
-				_parentContext.registerBeanDefinition(beanName, definition);
-			}
+		for (RequiredInterface required: getRequiredServices()) { 
+			String beanName = _required.get(required);
+			ConstructorArgumentValues cargs = new ConstructorArgumentValues();
+			cargs.addGenericArgumentValue(required.getName());
+			BeanDefinition definition = new RootBeanDefinition(
+					RequiredServiceBean.class, cargs,
+					new MutablePropertyValues());
+			_parentContext.registerBeanDefinition(beanName, definition);
 		}
 	}
 
 	@Override
 	protected void doStop() {
-	    _context.close();
+		_context.close();
 	}
 }
diff --git a/system/spring/src/test/java/org/wamblee/system/spring/SpringComponentTest.java b/system/spring/src/test/java/org/wamblee/system/spring/SpringComponentTest.java
index b0f7f8ab..0b4ffb08 100644
--- a/system/spring/src/test/java/org/wamblee/system/spring/SpringComponentTest.java
+++ b/system/spring/src/test/java/org/wamblee/system/spring/SpringComponentTest.java
@@ -10,11 +10,10 @@ import junit.framework.TestCase;
 import org.wamblee.io.ClassPathResource;
 import org.wamblee.system.DefaultProvidedInterfaceDescriptor;
 import org.wamblee.system.DefaultRequiredInterfaceDescriptor;
-import org.wamblee.system.DefaultServiceRegistry;
+import org.wamblee.system.DefaultService;
 import org.wamblee.system.ProvidedInterface;
 import org.wamblee.system.RequiredInterface;
 import org.wamblee.system.Service;
-import org.wamblee.system.ServiceRegistry;
 import org.wamblee.system.SystemAssemblyException;
 
 public class SpringComponentTest extends TestCase {
@@ -24,21 +23,18 @@ public class SpringComponentTest extends TestCase {
 	private static final String HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML = "test.org.wamblee.system.springWithProperties.xml";
     private static final String PROPERTY_FILE = "test.org.wamblee.system.spring.properties";
 
-	private ServiceRegistry _registry;
-
 	@Override
 	protected void setUp() throws Exception {
 		super.setUp();
-		_registry = new DefaultServiceRegistry();
 	}
 
 	public void testBlackboxSystem() {
-		SpringComponent system = new SpringComponent("system", _registry,
+		SpringComponent system = new SpringComponent("system",
 				new String[] { HELLO_SERVICE_SPRING_XML },
 				new HashMap<String, ProvidedInterface>(),
 				new HashMap<RequiredInterface, String>());
-		system.start("Hello", new Service[0]);
-		Service[] services = system.getRunningServices();
+		system.start("Hello");
+		ProvidedInterface[] services = system.getRunningServices();
 		assertEquals(0, services.length);
 		
 		system.stop();
@@ -49,14 +45,14 @@ public class SpringComponentTest extends TestCase {
 		provided.put("helloService", new DefaultProvidedInterfaceDescriptor(
 				"hello", HelloService.class));
 
-		SpringComponent system = new SpringComponent("system", _registry,
+		SpringComponent system = new SpringComponent("system", 
 				new String[] { HELLO_SERVICE_SPRING_XML }, provided,
 				new HashMap<RequiredInterface, String>());
-		system.start("Hello", new Service[0]);
-		Service[] services = system.getRunningServices();
+		system.start("Hello");
+		ProvidedInterface[] services = system.getRunningServices();
 		assertEquals(1, services.length);
-		assertTrue(services[0].reference(HelloService.class) instanceof HelloService);
-		assertEquals("Hello world!", services[0].reference(HelloService.class)
+		assertTrue(services[0].getImplementation() instanceof HelloService);
+		assertEquals("Hello world!", ((HelloService)services[0].getImplementation())
 				.say());
 		system.stop();
 	}
@@ -65,7 +61,7 @@ public class SpringComponentTest extends TestCase {
 		Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
 		provided.put("helloService", new DefaultProvidedInterfaceDescriptor(
 				"hello", HelloService.class));
-		SpringComponent system = new SpringComponent("system", _registry,
+		SpringComponent system = new SpringComponent("system", 
 				new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML },
 				provided,
 				new HashMap<RequiredInterface, String>());
@@ -73,18 +69,19 @@ public class SpringComponentTest extends TestCase {
 		props.load(new ClassPathResource(PROPERTY_FILE).getInputStream());
 		system.addProperties(props);
 		
-		system.start("Hello", new Service[0]);
-		Service[] services = system.getRunningServices();
-		assertEquals("Property Value", services[0].reference(HelloService.class).say());
+		system.start("Hello");
+		ProvidedInterface[] services = system.getRunningServices();
+		assertEquals("Property Value", 
+				((HelloService)services[0].getImplementation()).say());
 	}
 
 	public void testWithMissingRequirement() {
 		try {
-			SpringComponent system = new SpringComponent("system", _registry,
+			SpringComponent system = new SpringComponent("system",
 					new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
 					new HashMap<String, ProvidedInterface>(),
 					new HashMap<RequiredInterface, String>());
-			system.start("Bla", new Service[0]);
+			system.start("Bla");
 		} catch (SystemAssemblyException e) {
 			//e.printStackTrace();
 			return;
@@ -96,13 +93,16 @@ public class SpringComponentTest extends TestCase {
 		Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
 		required.put(new DefaultRequiredInterfaceDescriptor("hello", HelloService.class),
 				"helloService");
-		SpringComponent system = new SpringComponent("system", _registry,
+		SpringComponent system = new SpringComponent("system",
 				new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
 				new HashMap<String, ProvidedInterface>(), required);
 		
 		HelloService helloObject = new HelloService("ladida"); 
-		Service helloService = _registry.register(new DefaultProvidedInterfaceDescriptor("hello", HelloService.class), helloObject);
-		system.start("Bla", new Service[] { helloService } );
+		ProvidedInterface helloService = new DefaultProvidedInterfaceDescriptor("hello", HelloService.class);
+		helloService.publish(helloObject);
+		system.getRequiredServices()[0].setProvider(helloService);
+		
+		system.start("Bla");
 		system.stop();
 	}
 	
@@ -114,18 +114,22 @@ public class SpringComponentTest extends TestCase {
 		provided.put("blaService", new DefaultProvidedInterfaceDescriptor("bla",
 				BlaService.class));
 
-		SpringComponent system = new SpringComponent("system", _registry,
+		SpringComponent system = new SpringComponent("system",
 				new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
 				provided, required);
 		
 		HelloService helloObject = new HelloService("ladida"); 
-		Service helloService = _registry.register(new DefaultProvidedInterfaceDescriptor("hello", HelloService.class), helloObject);
-		Service[] services = system.start("Bla", new Service[] { helloService } );
-		assertEquals(1, services.length);
+		ProvidedInterface helloService = 
+			new DefaultProvidedInterfaceDescriptor("hello", HelloService.class);
+		helloService.publish(helloObject);
+		system.getRequiredServices()[0].setProvider(helloService);
+		system.start("Bla");
+		ProvidedInterface started = system.getProvidedServices()[0];
 		
-		assertTrue(services[0].reference(BlaService.class) instanceof BlaService);
-		assertEquals("ladida", services[0].reference(BlaService.class)
-				.execute());
+	    assertNotNull(started.getImplementation());
+	    assertTrue(started.getImplementation() instanceof BlaService);
+		assertEquals("ladida", 
+				((BlaService)started.getImplementation()).execute());
 		system.stop();
 	}
 
-- 
2.31.1