source code formatting.
[utils] / system / general / src / test / java / org / wamblee / system / container / ContainerTest.java
index bda07b218a62d5b64c9b4ab0c0ea476e1149e0a3..1d7d8a54c77e02d9cdb247635827862e7a233ff7 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright 2007 the original author or authors.
- * 
+ *
  * Licensed 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.
  */
 package org.wamblee.system.container;
 
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
 import junit.framework.TestCase;
 
 import org.wamblee.general.Pair;
+
 import org.wamblee.system.core.Component;
 import org.wamblee.system.core.DefaultProvidedInterface;
 import org.wamblee.system.core.DefaultRequiredInterface;
@@ -32,714 +29,852 @@ import org.wamblee.system.core.RequiredInterface;
 import org.wamblee.system.core.Scope;
 import org.wamblee.system.core.StringComponent;
 import org.wamblee.system.core.SystemAssemblyException;
+
 import org.wamblee.test.AssertionUtils;
 import org.wamblee.test.EventTracker;
 
-public class ContainerTest extends TestCase {
+import java.io.Serializable;
+
+import java.util.ArrayList;
+import java.util.List;
+
 
-       private EventTracker<String> tracker;
-
-       @Override
-       protected void setUp() throws Exception {
-               super.setUp();
-               tracker = new EventTracker<String>();
-       }
-
-       private static class MyMultiple implements Serializable, Runnable {
-               @Override
-               public void run() {
-                       // Empty
-               }
-       }
-
-       private List<Pair<ProvidedInterface, Component>> createProvidedInput(
-                       ProvidedInterface[] aProvided, Component aProvider) {
-               List<Pair<ProvidedInterface, Component>> result = new ArrayList<Pair<ProvidedInterface, Component>>();
-               for (ProvidedInterface provided : aProvided) {
-                       result.add(new Pair<ProvidedInterface, Component>(provided,
-                                       aProvider));
-               }
-               return result;
-       }
-
-       public void testEnvironmentApplication() {
-               Environment environment = new Environment(tracker);
-               Application application = new Application(tracker);
-               Container container = new Container("root", new Component[] {
-                               environment, application }, new ProvidedInterface[0],
-                               new RequiredInterface[0]);
-               Scope scope = container.start();
-               assertTrue(container.isSealed());
-               AssertionUtils.assertEquals(new String[] { "start.environment",
-                               "start.application" }, tracker.getEvents(
-                               Thread.currentThread()).toArray(new String[0]));
-               assertEquals(0, scope.getProvidedInterfaces().size());
-
-               assertEquals(environment.getString(), application.getString());
-               assertEquals(environment.getInteger(), application.getInteger());
-
-       }
-
-       public void testEnvironmentApplicationSimpleConstructor() {
-               Environment environment = new Environment(tracker);
-               Application application = new Application(tracker);
-               Container container = new Container("root").addComponent(environment)
-                               .addComponent(application);
-
-               Scope scope = container.start();
-               AssertionUtils.assertEquals(new String[] { "start.environment",
-                               "start.application" }, tracker.getEvents(
-                               Thread.currentThread()).toArray(new String[0]));
-               assertEquals(0, scope.getProvidedInterfaces().size());
-
-               assertEquals(environment.getString(), application.getString());
-               assertEquals(environment.getInteger(), application.getInteger());
-
-       }
-
-       public void testApplicationEnvironment() {
-               try {
-                       Component<?> environment = new Environment();
-                       Component<?> application = new Application();
-                       Container container = new Container("root", new Component[] {
-                                       application, environment }, new ProvidedInterface[0],
-                                       new RequiredInterface[0]);
-                       container.start();
-               } catch (SystemAssemblyException e) {
-                       // e.printStackTrace();
-                       return;
-               }
-               fail();
-       }
-
-       public void testComposite() {
-               Component<?> environment = new Environment(tracker);
-               Component<?> application = new Application(tracker);
-               assertEquals(0, tracker.getEventCount());
-
-               Container system = new Container("all", new Component[] { environment,
-                               application }, new ProvidedInterface[0],
-                               new RequiredInterface[0]);
-               Scope runtime = system.start();
-               List<RequiredInterface> required = system.getRequiredInterfaces();
-               assertEquals(0, required.size());
-               List<ProvidedInterface> provided = system.getProvidedInterfaces();
-               assertEquals(0, provided.size());
-
-               AssertionUtils.assertEquals(new String[] { "start.environment",
-                               "start.application" }, tracker.getEvents(
-                               Thread.currentThread()).toArray(new String[0]));
-               tracker.clear();
-
-               system.stop(runtime);
-               AssertionUtils.assertEquals(new String[] { "stop.application",
-                               "stop.environment" }, tracker
-                               .getEvents(Thread.currentThread()).toArray(new String[0]));
-
-       }
-
-       public void testCompositeWithWrongProvidedInfo() {
-               try {
-                       Component<?> environment = new Environment();
-                       Component<?> application = new Application();
-                       Container system = new Container("all", new Component[] {
-                                       environment, application },
-                                       new ProvidedInterface[] { new DefaultProvidedInterface(
-                                                       "float", Float.class) },
-                                       new DefaultRequiredInterface[0]);
-                       system.validate();
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               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 DefaultRequiredInterface(
-                                                       "string", String.class) });
-                       system.start();
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               fail();
-       }
-
-       public void testCompositeWithSuperfluousRequiredInfo() {
-               Component<?> environment = new Environment();
-               Component<?> application = new Application();
-               Container system = new Container("all", new Component[] { environment,
-                               application }, new ProvidedInterface[0],
-                               new RequiredInterface[] { new DefaultRequiredInterface("float",
-                                               Float.class) });
-               system.getRequiredInterfaces().get(0).setProvider(
-                               new DefaultProvidedInterface("hallo", Float.class));
-               system.start();
-               List<RequiredInterface> required = system.getRequiredInterfaces();
-               assertEquals(1, required.size());
-               List<ProvidedInterface> provided = system.getProvidedInterfaces();
-               assertEquals(0, provided.size());
-       }
-
-       public void testCompositeWithExternalDependencesNotProvided() {
-               try {
-                       Component<?> application = new Application();
-
-                       Container system = new Container("all",
-                                       new Component[] { application }, new ProvidedInterface[0],
-                                       application.getRequiredInterfaces().toArray(
-                                                       new RequiredInterface[0]));
-                       system.start();
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               fail();
-       }
-
-       public void testDuplicateComponent() {
-               try {
-                       Component<?> comp1 = new Application();
-                       Component<?> comp2 = new Application();
-                       Container system = new Container("top");
-                       system.addComponent(comp1).addComponent(comp2);
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               fail();
-       }
-
-       public void testInconsistentHierarchy() {
-               try {
-                       Component<?> comp = new Application();
-                       Container system = new Container("top").addComponent(comp);
-                       Container system2 = new Container("top2").addComponent(comp);
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               fail();
-       }
-
-       public void testCompositeWithExternalDependencesProvided() {
-
-               Component<?> environment = new Environment();
-               Component<?> application = new Application();
-               Container system = new Container("all",
-                               new Component[] { application }, new ProvidedInterface[0],
-                               application.getRequiredInterfaces().toArray(
-                                               new RequiredInterface[0]));
-               environment.start(new DefaultScope(new ProvidedInterface[0]));
-               system.getRequiredInterfaces().get(0).setProvider(
-                               environment.getProvidedInterfaces().get(0));
-               system.getRequiredInterfaces().get(1).setProvider(
-                               environment.getProvidedInterfaces().get(1));
-
-               system.start();
-               List<RequiredInterface> required = system.getRequiredInterfaces();
-               assertEquals(2, required.size());
-               List<ProvidedInterface> provided = system.getProvidedInterfaces();
-               assertEquals(0, provided.size());
-
-       }
-
-       public void testAmbiguousInterfaces() {
-               try {
-                       Component<?> environment1 = new Environment();
-                       Component<?> environment2 = new Environment();
-                       Component<?> application = new Application();
-                       Container container = new Container("root", new Component[] {
-                                       environment1, environment2, application },
-                                       new ProvidedInterface[0], new RequiredInterface[0]);
-                       container.start();
-
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               fail();
-       }
-
-       public void testIncompleteRequirements() {
-               try {
-                       Component<?> application = new Application();
-                       Container system = new Container("all",
-                                       new Component[] { application }, new ProvidedInterface[0],
-                                       new RequiredInterface[0]);
-                       system.start();
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               fail();
-       }
-
-       public void testEnvironmentApplicationRollbackOnException()
-                       throws Exception {
-               Environment environment = new Environment(tracker);
-               Application application = new Application() { 
-                       @Override
-                       public Object doStart(Scope aScope) {
-                               throw new RuntimeException();
-                       }
-               };
-               
-               try {
-                       Container container = new Container("root", new Component[] {
-                                       environment, application }, new ProvidedInterface[0],
-                                       new RequiredInterface[0]);
-
-                       container.start();
-               } catch (RuntimeException e) {
-                       AssertionUtils.assertEquals(new String[] { "start.environment",
-                                       "stop.environment" }, tracker.getEvents(
-                                       Thread.currentThread()).toArray(new String[0]));
-                       return;
-               }
-               fail();
-       }
-
-       public void testEnvironmentApplicationRollbackOnExceptionWithExceptionOnStop()
-                       throws Exception {
-
-               Environment environment = new Environment(tracker);
-               // Application 1 will throw an exception while stopping.
-               Application application1 = new Application("app1")  {
-                       @Override
-                       public void doStop(Object aRuntime) {
-                               throw new RuntimeException();
-                       }
-               };
-
-               // application 2 will throw an exception while starting
-               Application application2 = new Application("app2") {
-                       public Object doStart(Scope aScope) { 
-                               throw new RuntimeException();
-                       }
-               };
-
-               try {
-                       Container container = new Container("root", new Component[] {
-                                       environment, application1, application2 },
-                                       new ProvidedInterface[0], new RequiredInterface[0]);
-
-                       container.start();
-               } catch (RuntimeException e) {
-                       AssertionUtils.assertEquals(new String[] { "start.environment",
-                                       "stop.environment" }, tracker.getEvents(
-                                       Thread.currentThread()).toArray(new String[0]));
-                       return;
-               }
-               fail();
-       }
-
-       public void testOptionalRequiredInterfaceProvidedOptionalInternal() {
-               Application application = new Application(true);
-               Container container = new Container("top",
-                               new Component[] { application }, new ProvidedInterface[0],
-                               Application.required(true));
-               Environment env = new Environment();
-               container.getRequiredInterfaces().get(0).setProvider(
-                               env.getProvidedInterfaces().get(0));
-               container.getRequiredInterfaces().get(1).setProvider(
-                               env.getProvidedInterfaces().get(1));
-               Scope external = new DefaultScope(env.getProvidedInterfaces());
-               env.start(external);
-
-               container.start(external);
-               assertSame(env.getProvidedInterfaces().get(0), container
-                               .getRequiredInterfaces().get(0).getProvider());
-               assertSame(env.getProvidedInterfaces().get(1), container
-                               .getRequiredInterfaces().get(1).getProvider());
-               assertSame(env.getProvidedInterfaces().get(0), application
-                               .getRequiredInterfaces().get(0).getProvider());
-               assertSame(env.getProvidedInterfaces().get(1), application
-                               .getRequiredInterfaces().get(1).getProvider());
-       }
-
-       public void testOptionalRequiredInterfaceNotProvidedOptionalInternal() {
-               Application application = new Application(true);
-               Container container = new Container("top",
-                               new Component[] { application }, new ProvidedInterface[0],
-                               Application.required(true));
-               Environment env = new Environment();
-               container.getRequiredInterfaces().get(0).setProvider(
-                               env.getProvidedInterfaces().get(0));
-               Scope external = new DefaultScope(new ProvidedInterface[0]);
-               external.publishInterface(env.getProvidedInterfaces().get(0), env
-                               .getString());
-               container.start(external);
-               assertSame(env.getProvidedInterfaces().get(0), container
-                               .getRequiredInterfaces().get(0).getProvider());
-               assertNull(container.getRequiredInterfaces().get(1).getProvider());
-               assertSame(env.getProvidedInterfaces().get(0), application
-                               .getRequiredInterfaces().get(0).getProvider());
-               assertNull(application.getRequiredInterfaces().get(1).getProvider());
-       }
-
-       public void testOptionalRequiredInterfaceProvidedMandatoryInternal() {
-               Application application = new Application();
-               Container container = new Container("top",
-                               new Component[] { application }, new ProvidedInterface[0],
-                               Application.required(true));
-               Environment env = new Environment();
-               container.getRequiredInterfaces().get(0).setProvider(
-                               env.getProvidedInterfaces().get(0));
-               container.getRequiredInterfaces().get(1).setProvider(
-                               env.getProvidedInterfaces().get(1));
-               try {
-                       container.start();
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               fail();
-       }
-
-       public void testSealed() {
-               final Container container = new Container("xx");
-               assertFalse(container.isSealed());
-               container.start();
-               assertTrue(container.isSealed());
-
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.addComponent(new Application());
-                       }
-               }, SystemAssemblyException.class);
-
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectRequiredProvided("x", "y", "a", "b");
-                       }
-               }, SystemAssemblyException.class);
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectExternalRequired("x", "y", "a");
-                       }
-               }, SystemAssemblyException.class);
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectExternalProvided("x", "y", "z");
-                       }
-               }, SystemAssemblyException.class);
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.addProvidedInterface(new DefaultProvidedInterface(
-                                               "xx", String.class));
-                       }
-               }, SystemAssemblyException.class);
-
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.addRequiredInterface(new DefaultRequiredInterface(
-                                               "xx", String.class));
-                       }
-               }, SystemAssemblyException.class);
-       }
-
-       public void testRestriction() {
-               Environment env1 = new Environment("env1");
-               Environment env2 = new Environment("env2");
-               Application app = new Application("app");
-               Container container = new Container("top").addComponent(env1)
-                               .addComponent(env2).addComponent(app);
-               container.connectRequiredProvided("app", null, "env1", null);
-               container.start();
-               assertEquals(env1.getString(), app.getString());
-               assertEquals(env1.getInteger(), app.getInteger());
-               assertFalse(env2.getString().equals(app.getString()));
-               assertFalse(env2.getInteger().equals(app.getInteger()));
-       }
-
-       public void testRestrictionWithFromAndToInterfaceName() {
-               Environment env1 = new Environment("env1");
-               Environment env2 = new Environment("env2");
-               Application app = new Application("app");
-               Container container = new Container("top").addComponent(env1)
-                               .addComponent(env2).addComponent(app);
-               container.connectRequiredProvided("app", app.getRequiredInterfaces()
-                               .get(0).getName(), "env1", env1.getProvidedInterfaces().get(0)
-                               .getName());
-               container.connectRequiredProvided("app", app.getRequiredInterfaces()
-                               .get(1).getName(), "env2", env2.getProvidedInterfaces().get(1)
-                               .getName());
-               container.start();
-               assertEquals(env1.getString(), app.getString());
-               assertEquals(env2.getInteger(), app.getInteger());
-               assertFalse(env2.getString().equals(app.getString()));
-               assertFalse(env1.getInteger().equals(app.getInteger()));
-       }
-
-       public void testRestrictionWrongComponentNames() {
-               Environment env1 = new Environment("env1");
-               Environment env2 = new Environment("env2");
-               Application app = new Application("app");
-               final Container container = new Container("top").addComponent(env1)
-                               .addComponent(env2).addComponent(app);
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectRequiredProvided("app2", null, "env1", null);
-                       }
-               }, SystemAssemblyException.class);
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectRequiredProvided("app", null, "env3", null);
-                       }
-               }, SystemAssemblyException.class);
-       }
-
-       public void testRestrictionWrongInterfaceNames() {
-               final Environment env1 = new Environment("env1");
-               Environment env2 = new Environment("env2");
-               final Application app = new Application("app");
-               final Container container = new Container("top").addComponent(env1)
-                               .addComponent(env2).addComponent(app);
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectRequiredProvided("app", app
-                                               .getRequiredInterfaces().get(0).getName()
-                                               + "xxx", "env1", null);
-                       }
-               }, SystemAssemblyException.class);
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectRequiredProvided("app", null, "env1", env1
-                                               .getProvidedInterfaces().get(0).getName()
-                                               + "yyy");
-                       }
-               }, SystemAssemblyException.class);
-       }
-
-       public void testProvidedInDifferentScopes() {
-               // Scoping problem occurred. Externally and internally provided
-               // components clashed
-               // because unique id generation in the scope was wrong.
-
-               StringComponent str = new StringComponent("string");
-               Application app = new Application("app");
-               Container container = new Container("top").addComponent(str)
-                               .addComponent(app);
-               container.addRequiredInterface(new DefaultRequiredInterface("integer",
-                               Integer.class));
-
-               ProvidedInterface provided = new DefaultProvidedInterface("hallo",
-                               Integer.class);
-               container.getRequiredInterfaces().get(0).setProvider(provided);
-
-               Scope external = new DefaultScope(new ProvidedInterface[0]);
-               external.publishInterface(provided, 100);
-               Scope scope = container.start(external);
-       }
-
-       public void testProvidedInterfaces() {
-               Environment env = new Environment(tracker);
-               Container envcontainer = new Container("0").addComponent(env)
-                               .addProvidedInterface(
-                                               new DefaultProvidedInterface("string", String.class))
-                               .addProvidedInterface(
-                                               new DefaultProvidedInterface("integer", Integer.class));
-               Scope scope = envcontainer.start();
-
-               AssertionUtils.assertEquals(new String[] { "start.environment" },
-                               tracker.getEvents(Thread.currentThread()).toArray(
-                                               new String[0]));
-
-               envcontainer.stop(scope);
-       }
-
-       public void testCoupleTwoContainers() {
-               Environment env = new Environment(tracker);
-               Container envcontainer = new Container("0").addComponent(env)
-                               .addProvidedInterface(
-                                               new DefaultProvidedInterface("string", String.class))
-                               .addProvidedInterface(
-                                               new DefaultProvidedInterface("integer", Integer.class));
-
-               Application app = new Application(tracker);
-               Container appcontainer = new Container("1").addComponent(app)
-                               .addRequiredInterface(
-                                               new DefaultRequiredInterface("string", String.class))
-                               .addRequiredInterface(
-                                               new DefaultRequiredInterface("integer", Integer.class));
-
-               Container top = new Container("top");
-               top.addComponent(envcontainer).addComponent(appcontainer);
-
-               top.start();
-               AssertionUtils.assertEquals(new String[] { "start.environment",
-                               "start.application" }, tracker.getEvents(
-                               Thread.currentThread()).toArray(new String[0]));
-
-       }
-
-       public void testNonUniqueRequiredInterface() {
-               final Container container = new Container("top");
-               container.addRequiredInterface(new DefaultRequiredInterface("i",
-                               Integer.class));
-               container.addRequiredInterface(new DefaultRequiredInterface("x",
-                               String.class));
-               container.addRequiredInterface(new DefaultRequiredInterface("y",
-                               String.class));
-
-               Application app = new Application("1");
-               container.addComponent(app);
-
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.start();
-                       }
-               }, SystemAssemblyException.class);
-
-               container.connectExternalRequired("1", app.getRequiredInterfaces().get(
-                               0).getName(), "y");
-
-               ProvidedInterface i = new DefaultProvidedInterface("i", Integer.class);
-               ProvidedInterface x = new DefaultProvidedInterface("x", String.class);
-               ProvidedInterface y = new DefaultProvidedInterface("y", String.class);
-
-               Scope externalScope = new DefaultScope(new ProvidedInterface[0]);
-
-               externalScope.publishInterface(i, 100);
-               externalScope.publishInterface(x, "x-value");
-               externalScope.publishInterface(y, "y-value");
-
-               container.getRequiredInterfaces().get(0).setProvider(i);
-               container.getRequiredInterfaces().get(1).setProvider(x);
-               container.getRequiredInterfaces().get(2).setProvider(y);
-
-               Scope runtime = container.start(externalScope);
-
-               assertEquals("y-value", app.getString());
-
-       }
-
-       public void testNonUniqueRequiredInterfaceWrongNames() {
-               final Container container = new Container("top");
-               container.addRequiredInterface(new DefaultRequiredInterface("i",
-                               Integer.class));
-               container.addRequiredInterface(new DefaultRequiredInterface("x",
-                               String.class));
-               container.addRequiredInterface(new DefaultRequiredInterface("y",
-                               String.class));
-
-               final Application app = new Application("1");
-               container.addComponent(app);
-
-               // wrong component name.
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectExternalRequired("2", "x", "y");
-                       }
-               }, SystemAssemblyException.class);
-
-               // Wrong interface name of component.
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectExternalRequired("1", app
-                                               .getRequiredInterfaces().get(0).getName()
-                                               + "xxx", "y");
-                       }
-               }, SystemAssemblyException.class);
-
-               // Wrong external interface name of container
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectExternalRequired("1", app
-                                               .getRequiredInterfaces().get(0).getName(), "z");
-                       }
-               }, SystemAssemblyException.class);
-       }
-
-       public void testNonUniqueProvidedInterface() {
-
-               final Container container = new Container("top")
-                               .addProvidedInterface(new DefaultProvidedInterface("external",
-                                               String.class));
-               Environment env1 = new Environment("env1");
-               Environment env2 = new Environment("env2");
-
-               container.addComponent(env1);
-               container.addComponent(env2);
-
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.start();
-                       }
-               }, SystemAssemblyException.class);
-
-               // now choose env2
-
-               container.connectExternalProvided(container.getProvidedInterfaces()
-                               .get(0).getName(), env2.getName(), env2.getProvidedInterfaces()
-                               .get(0).getName());
-
-               Scope scope = container.start();
-
-               // check the value of the provided interface of the container
-
-               String value = scope.getInterfaceImplementation(container
-                               .getProvidedInterfaces().get(0), String.class);
-               assertNotNull(value);
-               assertEquals(value, env2.getString());
-               assertFalse(value.equals(env1.getString()));
-       }
-
-       public void testNonUniqueProvidedInterfaceWrongNames() {
-
-               final Container container = new Container("top")
-                               .addProvidedInterface(new DefaultProvidedInterface("external",
-                                               String.class));
-               final Environment env1 = new Environment("env1");
-               final Environment env2 = new Environment("env2");
-
-               container.addComponent(env1);
-               container.addComponent(env2);
-
-               // Wrong external provided interface name
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectExternalProvided(container
-                                               .getProvidedInterfaces().get(0).getName()
-                                               + "xx", "env1", env1.getProvidedInterfaces().get(0)
-                                               .getName());
-                       }
-               }, SystemAssemblyException.class);
-
-               // Wrong provided interface name.
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectExternalProvided(container
-                                               .getProvidedInterfaces().get(0).getName(), "env1", env1
-                                               .getProvidedInterfaces().get(0).getName()
-                                               + "xx");
-                       }
-               }, SystemAssemblyException.class);
-
-               // Wrong provided component
-               AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
-                       @Override
-                       public void run() throws Exception {
-                               container.connectExternalProvided(container
-                                               .getProvidedInterfaces().get(0).getName(), "env3", env1
-                                               .getProvidedInterfaces().get(0).getName());
-                       }
-               }, SystemAssemblyException.class);
-       }
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+  */
+public class ContainerTest extends TestCase {
+    /**
+     * DOCUMENT ME!
+     */
+    private EventTracker<String> tracker;
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        tracker = new EventTracker<String>();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param aProvided DOCUMENT ME!
+     * @param aProvider DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    private List<Pair<ProvidedInterface, Component>> createProvidedInput(
+        ProvidedInterface[] aProvided, Component aProvider) {
+        List<Pair<ProvidedInterface, Component>> result = new ArrayList<Pair<ProvidedInterface, Component>>();
+
+        for (ProvidedInterface provided : aProvided) {
+            result.add(new Pair<ProvidedInterface, Component>(provided,
+                    aProvider));
+        }
+
+        return result;
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testEnvironmentApplication() {
+        Environment environment = new Environment(tracker);
+        Application application = new Application(tracker);
+        Container   container   = new Container("root",
+                new Component[] { environment, application },
+                new ProvidedInterface[0], new RequiredInterface[0]);
+        Scope       scope       = container.start();
+        assertTrue(container.isSealed());
+        AssertionUtils.assertEquals(new String[] {
+                "start.environment", "start.application"
+            }, tracker.getEvents(Thread.currentThread()).toArray(new String[0]));
+        assertEquals(0, scope.getProvidedInterfaces().size());
+
+        assertEquals(environment.getString(), application.getString());
+        assertEquals(environment.getInteger(), application.getInteger());
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testEnvironmentApplicationSimpleConstructor() {
+        Environment environment = new Environment(tracker);
+        Application application = new Application(tracker);
+        Container   container   = new Container("root").addComponent(environment)
+            .addComponent(application);
+
+        Scope       scope       = container.start();
+        AssertionUtils.assertEquals(new String[] {
+                "start.environment", "start.application"
+            }, tracker.getEvents(Thread.currentThread()).toArray(new String[0]));
+        assertEquals(0, scope.getProvidedInterfaces().size());
+
+        assertEquals(environment.getString(), application.getString());
+        assertEquals(environment.getInteger(), application.getInteger());
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testApplicationEnvironment() {
+        try {
+            Component<?> environment = new Environment();
+            Component<?> application = new Application();
+            Container    container   = new Container("root",
+                    new Component[] { application, environment },
+                    new ProvidedInterface[0], new RequiredInterface[0]);
+            container.start();
+        } catch (SystemAssemblyException e) {
+            // e.printStackTrace();
+            return;
+        }
+
+        fail();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testComposite() {
+        Component<?> environment = new Environment(tracker);
+        Component<?> application = new Application(tracker);
+        assertEquals(0, tracker.getEventCount());
+
+        Container               system   = new Container("all",
+                new Component[] { environment, application },
+                new ProvidedInterface[0], new RequiredInterface[0]);
+        Scope                   runtime  = system.start();
+        List<RequiredInterface> required = system.getRequiredInterfaces();
+        assertEquals(0, required.size());
+
+        List<ProvidedInterface> provided = system.getProvidedInterfaces();
+        assertEquals(0, provided.size());
+
+        AssertionUtils.assertEquals(new String[] {
+                "start.environment", "start.application"
+            }, tracker.getEvents(Thread.currentThread()).toArray(new String[0]));
+        tracker.clear();
+
+        system.stop(runtime);
+        AssertionUtils.assertEquals(new String[] {
+                "stop.application", "stop.environment"
+            }, tracker.getEvents(Thread.currentThread()).toArray(new String[0]));
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testCompositeWithWrongProvidedInfo() {
+        try {
+            Component<?> environment = new Environment();
+            Component<?> application = new Application();
+            Container    system      = new Container("all",
+                    new Component[] { environment, application },
+                    new ProvidedInterface[] {
+                        new DefaultProvidedInterface("float", Float.class)
+                    }, new DefaultRequiredInterface[0]);
+            system.validate();
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+
+        fail();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    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 DefaultRequiredInterface("string", String.class)
+                    });
+            system.start();
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+
+        fail();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testCompositeWithSuperfluousRequiredInfo() {
+        Component<?> environment = new Environment();
+        Component<?> application = new Application();
+        Container    system      = new Container("all",
+                new Component[] { environment, application },
+                new ProvidedInterface[0],
+                new RequiredInterface[] {
+                    new DefaultRequiredInterface("float", Float.class)
+                });
+        system.getRequiredInterfaces().get(0)
+        .setProvider(new DefaultProvidedInterface("hallo", Float.class));
+        system.start();
+
+        List<RequiredInterface> required = system.getRequiredInterfaces();
+        assertEquals(1, required.size());
+
+        List<ProvidedInterface> provided = system.getProvidedInterfaces();
+        assertEquals(0, provided.size());
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testCompositeWithExternalDependencesNotProvided() {
+        try {
+            Component<?> application = new Application();
+
+            Container    system      = new Container("all",
+                    new Component[] { application }, new ProvidedInterface[0],
+                    application.getRequiredInterfaces()
+                    .toArray(new RequiredInterface[0]));
+            system.start();
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+
+        fail();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testDuplicateComponent() {
+        try {
+            Component<?> comp1  = new Application();
+            Component<?> comp2  = new Application();
+            Container    system = new Container("top");
+            system.addComponent(comp1).addComponent(comp2);
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+
+        fail();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testInconsistentHierarchy() {
+        try {
+            Component<?> comp    = new Application();
+            Container    system  = new Container("top").addComponent(comp);
+            Container    system2 = new Container("top2").addComponent(comp);
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+
+        fail();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testCompositeWithExternalDependencesProvided() {
+        Component<?> environment = new Environment();
+        Component<?> application = new Application();
+        Container    system      = new Container("all",
+                new Component[] { application }, new ProvidedInterface[0],
+                application.getRequiredInterfaces()
+                .toArray(new RequiredInterface[0]));
+        environment.start(new DefaultScope(new ProvidedInterface[0]));
+        system.getRequiredInterfaces().get(0)
+        .setProvider(environment.getProvidedInterfaces().get(0));
+        system.getRequiredInterfaces().get(1)
+        .setProvider(environment.getProvidedInterfaces().get(1));
+
+        system.start();
+
+        List<RequiredInterface> required = system.getRequiredInterfaces();
+        assertEquals(2, required.size());
+
+        List<ProvidedInterface> provided = system.getProvidedInterfaces();
+        assertEquals(0, provided.size());
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testAmbiguousInterfaces() {
+        try {
+            Component<?> environment1 = new Environment();
+            Component<?> environment2 = new Environment();
+            Component<?> application  = new Application();
+            Container    container    = new Container("root",
+                    new Component[] { environment1, environment2, application },
+                    new ProvidedInterface[0], new RequiredInterface[0]);
+            container.start();
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+
+        fail();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testIncompleteRequirements() {
+        try {
+            Component<?> application = new Application();
+            Container    system      = new Container("all",
+                    new Component[] { application }, new ProvidedInterface[0],
+                    new RequiredInterface[0]);
+            system.start();
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+
+        fail();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     * @throws RuntimeException DOCUMENT ME!
+     */
+    public void testEnvironmentApplicationRollbackOnException()
+        throws Exception {
+        Environment environment = new Environment(tracker);
+        Application application = new Application() {
+                @Override
+                public Object doStart(Scope aScope) {
+                    throw new RuntimeException();
+                }
+            };
+
+        try {
+            Container container = new Container("root",
+                    new Component[] { environment, application },
+                    new ProvidedInterface[0], new RequiredInterface[0]);
+
+            container.start();
+        } catch (RuntimeException e) {
+            AssertionUtils.assertEquals(new String[] {
+                    "start.environment", "stop.environment"
+                },
+                tracker.getEvents(Thread.currentThread()).toArray(new String[0]));
+
+            return;
+        }
+
+        fail();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     * @throws RuntimeException DOCUMENT ME!
+     */
+    public void testEnvironmentApplicationRollbackOnExceptionWithExceptionOnStop()
+        throws Exception {
+        Environment environment = new Environment(tracker);
+
+        // Application 1 will throw an exception while stopping.
+        Application application1 = new Application("app1") {
+                @Override
+                public void doStop(Object aRuntime) {
+                    throw new RuntimeException();
+                }
+            };
+
+        // application 2 will throw an exception while starting
+        Application application2 = new Application("app2") {
+                public Object doStart(Scope aScope) {
+                    throw new RuntimeException();
+                }
+            };
+
+        try {
+            Container container = new Container("root",
+                    new Component[] { environment, application1, application2 },
+                    new ProvidedInterface[0], new RequiredInterface[0]);
+
+            container.start();
+        } catch (RuntimeException e) {
+            AssertionUtils.assertEquals(new String[] {
+                    "start.environment", "stop.environment"
+                },
+                tracker.getEvents(Thread.currentThread()).toArray(new String[0]));
+
+            return;
+        }
+
+        fail();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testOptionalRequiredInterfaceProvidedOptionalInternal() {
+        Application application = new Application(true);
+        Container   container   = new Container("top",
+                new Component[] { application }, new ProvidedInterface[0],
+                Application.required(true));
+        Environment env         = new Environment();
+        container.getRequiredInterfaces().get(0)
+        .setProvider(env.getProvidedInterfaces().get(0));
+        container.getRequiredInterfaces().get(1)
+        .setProvider(env.getProvidedInterfaces().get(1));
+
+        Scope external = new DefaultScope(env.getProvidedInterfaces());
+        env.start(external);
+
+        container.start(external);
+        assertSame(env.getProvidedInterfaces().get(0),
+            container.getRequiredInterfaces().get(0).getProvider());
+        assertSame(env.getProvidedInterfaces().get(1),
+            container.getRequiredInterfaces().get(1).getProvider());
+        assertSame(env.getProvidedInterfaces().get(0),
+            application.getRequiredInterfaces().get(0).getProvider());
+        assertSame(env.getProvidedInterfaces().get(1),
+            application.getRequiredInterfaces().get(1).getProvider());
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testOptionalRequiredInterfaceNotProvidedOptionalInternal() {
+        Application application = new Application(true);
+        Container   container   = new Container("top",
+                new Component[] { application }, new ProvidedInterface[0],
+                Application.required(true));
+        Environment env         = new Environment();
+        container.getRequiredInterfaces().get(0)
+        .setProvider(env.getProvidedInterfaces().get(0));
+
+        Scope external = new DefaultScope(new ProvidedInterface[0]);
+        external.publishInterface(env.getProvidedInterfaces().get(0),
+            env.getString());
+        container.start(external);
+        assertSame(env.getProvidedInterfaces().get(0),
+            container.getRequiredInterfaces().get(0).getProvider());
+        assertNull(container.getRequiredInterfaces().get(1).getProvider());
+        assertSame(env.getProvidedInterfaces().get(0),
+            application.getRequiredInterfaces().get(0).getProvider());
+        assertNull(application.getRequiredInterfaces().get(1).getProvider());
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testOptionalRequiredInterfaceProvidedMandatoryInternal() {
+        Application application = new Application();
+        Container   container   = new Container("top",
+                new Component[] { application }, new ProvidedInterface[0],
+                Application.required(true));
+        Environment env         = new Environment();
+        container.getRequiredInterfaces().get(0)
+        .setProvider(env.getProvidedInterfaces().get(0));
+        container.getRequiredInterfaces().get(1)
+        .setProvider(env.getProvidedInterfaces().get(1));
+
+        try {
+            container.start();
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+
+        fail();
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testSealed() {
+        final Container container = new Container("xx");
+        assertFalse(container.isSealed());
+        container.start();
+        assertTrue(container.isSealed());
+
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.addComponent(new Application());
+                }
+            }, SystemAssemblyException.class);
+
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectRequiredProvided("x", "y", "a", "b");
+                }
+            }, SystemAssemblyException.class);
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectExternalRequired("x", "y", "a");
+                }
+            }, SystemAssemblyException.class);
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectExternalProvided("x", "y", "z");
+                }
+            }, SystemAssemblyException.class);
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.addProvidedInterface(new DefaultProvidedInterface(
+                            "xx", String.class));
+                }
+            }, SystemAssemblyException.class);
+
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.addRequiredInterface(new DefaultRequiredInterface(
+                            "xx", String.class));
+                }
+            }, SystemAssemblyException.class);
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testRestriction() {
+        Environment env1      = new Environment("env1");
+        Environment env2      = new Environment("env2");
+        Application app       = new Application("app");
+        Container   container = new Container("top").addComponent(env1)
+            .addComponent(env2).addComponent(app);
+        container.connectRequiredProvided("app", null, "env1", null);
+        container.start();
+        assertEquals(env1.getString(), app.getString());
+        assertEquals(env1.getInteger(), app.getInteger());
+        assertFalse(env2.getString().equals(app.getString()));
+        assertFalse(env2.getInteger().equals(app.getInteger()));
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testRestrictionWithFromAndToInterfaceName() {
+        Environment env1      = new Environment("env1");
+        Environment env2      = new Environment("env2");
+        Application app       = new Application("app");
+        Container   container = new Container("top").addComponent(env1)
+            .addComponent(env2).addComponent(app);
+        container.connectRequiredProvided("app",
+            app.getRequiredInterfaces().get(0).getName(), "env1",
+            env1.getProvidedInterfaces().get(0).getName());
+        container.connectRequiredProvided("app",
+            app.getRequiredInterfaces().get(1).getName(), "env2",
+            env2.getProvidedInterfaces().get(1).getName());
+        container.start();
+        assertEquals(env1.getString(), app.getString());
+        assertEquals(env2.getInteger(), app.getInteger());
+        assertFalse(env2.getString().equals(app.getString()));
+        assertFalse(env1.getInteger().equals(app.getInteger()));
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testRestrictionWrongComponentNames() {
+        Environment     env1      = new Environment("env1");
+        Environment     env2      = new Environment("env2");
+        Application     app       = new Application("app");
+        final Container container = new Container("top").addComponent(env1)
+            .addComponent(env2).addComponent(app);
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectRequiredProvided("app2", null, "env1", null);
+                }
+            }, SystemAssemblyException.class);
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectRequiredProvided("app", null, "env3", null);
+                }
+            }, SystemAssemblyException.class);
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testRestrictionWrongInterfaceNames() {
+        final Environment env1      = new Environment("env1");
+        Environment       env2      = new Environment("env2");
+        final Application app       = new Application("app");
+        final Container   container = new Container("top").addComponent(env1)
+            .addComponent(env2).addComponent(app);
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectRequiredProvided("app",
+                        app.getRequiredInterfaces().get(0).getName() + "xxx",
+                        "env1", null);
+                }
+            }, SystemAssemblyException.class);
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectRequiredProvided("app", null, "env1",
+                        env1.getProvidedInterfaces().get(0).getName() + "yyy");
+                }
+            }, SystemAssemblyException.class);
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testProvidedInDifferentScopes() {
+        // Scoping problem occurred. Externally and internally provided
+        // components clashed
+        // because unique id generation in the scope was wrong.
+        StringComponent str       = new StringComponent("string");
+        Application     app       = new Application("app");
+        Container       container = new Container("top").addComponent(str)
+            .addComponent(app);
+        container.addRequiredInterface(new DefaultRequiredInterface("integer",
+                Integer.class));
+
+        ProvidedInterface provided = new DefaultProvidedInterface("hallo",
+                Integer.class);
+        container.getRequiredInterfaces().get(0).setProvider(provided);
+
+        Scope external = new DefaultScope(new ProvidedInterface[0]);
+        external.publishInterface(provided, 100);
+
+        Scope scope = container.start(external);
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testProvidedInterfaces() {
+        Environment env          = new Environment(tracker);
+        Container   envcontainer = new Container("0").addComponent(env)
+            .addProvidedInterface(new DefaultProvidedInterface("string",
+                    String.class))
+            .addProvidedInterface(new DefaultProvidedInterface("integer",
+                    Integer.class));
+        Scope       scope        = envcontainer.start();
+
+        AssertionUtils.assertEquals(new String[] { "start.environment" },
+            tracker.getEvents(Thread.currentThread()).toArray(new String[0]));
+
+        envcontainer.stop(scope);
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testCoupleTwoContainers() {
+        Environment env          = new Environment(tracker);
+        Container   envcontainer = new Container("0").addComponent(env)
+            .addProvidedInterface(new DefaultProvidedInterface("string",
+                    String.class))
+            .addProvidedInterface(new DefaultProvidedInterface("integer",
+                    Integer.class));
+
+        Application app          = new Application(tracker);
+        Container   appcontainer = new Container("1").addComponent(app)
+            .addRequiredInterface(new DefaultRequiredInterface("string",
+                    String.class))
+            .addRequiredInterface(new DefaultRequiredInterface("integer",
+                    Integer.class));
+
+        Container   top          = new Container("top");
+        top.addComponent(envcontainer).addComponent(appcontainer);
+
+        top.start();
+        AssertionUtils.assertEquals(new String[] {
+                "start.environment", "start.application"
+            }, tracker.getEvents(Thread.currentThread()).toArray(new String[0]));
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testNonUniqueRequiredInterface() {
+        final Container container = new Container("top");
+        container.addRequiredInterface(new DefaultRequiredInterface("i",
+                Integer.class));
+        container.addRequiredInterface(new DefaultRequiredInterface("x",
+                String.class));
+        container.addRequiredInterface(new DefaultRequiredInterface("y",
+                String.class));
+
+        Application app = new Application("1");
+        container.addComponent(app);
+
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.start();
+                }
+            }, SystemAssemblyException.class);
+
+        container.connectExternalRequired("1",
+            app.getRequiredInterfaces().get(0).getName(), "y");
+
+        ProvidedInterface i             = new DefaultProvidedInterface("i",
+                Integer.class);
+        ProvidedInterface x             = new DefaultProvidedInterface("x",
+                String.class);
+        ProvidedInterface y             = new DefaultProvidedInterface("y",
+                String.class);
+
+        Scope             externalScope = new DefaultScope(new ProvidedInterface[0]);
+
+        externalScope.publishInterface(i, 100);
+        externalScope.publishInterface(x, "x-value");
+        externalScope.publishInterface(y, "y-value");
+
+        container.getRequiredInterfaces().get(0).setProvider(i);
+        container.getRequiredInterfaces().get(1).setProvider(x);
+        container.getRequiredInterfaces().get(2).setProvider(y);
+
+        Scope runtime = container.start(externalScope);
+
+        assertEquals("y-value", app.getString());
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testNonUniqueRequiredInterfaceWrongNames() {
+        final Container container = new Container("top");
+        container.addRequiredInterface(new DefaultRequiredInterface("i",
+                Integer.class));
+        container.addRequiredInterface(new DefaultRequiredInterface("x",
+                String.class));
+        container.addRequiredInterface(new DefaultRequiredInterface("y",
+                String.class));
+
+        final Application app = new Application("1");
+        container.addComponent(app);
+
+        // wrong component name.
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectExternalRequired("2", "x", "y");
+                }
+            }, SystemAssemblyException.class);
+
+        // Wrong interface name of component.
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectExternalRequired("1",
+                        app.getRequiredInterfaces().get(0).getName() + "xxx",
+                        "y");
+                }
+            }, SystemAssemblyException.class);
+
+        // Wrong external interface name of container
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectExternalRequired("1",
+                        app.getRequiredInterfaces().get(0).getName(), "z");
+                }
+            }, SystemAssemblyException.class);
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testNonUniqueProvidedInterface() {
+        final Container container = new Container("top").addProvidedInterface(new DefaultProvidedInterface(
+                    "external", String.class));
+        Environment     env1      = new Environment("env1");
+        Environment     env2      = new Environment("env2");
+
+        container.addComponent(env1);
+        container.addComponent(env2);
+
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.start();
+                }
+            }, SystemAssemblyException.class);
+
+        // now choose env2
+        container.connectExternalProvided(container.getProvidedInterfaces()
+            .get(0).getName(), env2.getName(),
+            env2.getProvidedInterfaces().get(0).getName());
+
+        Scope scope = container.start();
+
+        // check the value of the provided interface of the container
+        String value = scope.getInterfaceImplementation(container.getProvidedInterfaces()
+                .get(0), String.class);
+        assertNotNull(value);
+        assertEquals(value, env2.getString());
+        assertFalse(value.equals(env1.getString()));
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void testNonUniqueProvidedInterfaceWrongNames() {
+        final Container   container = new Container("top").addProvidedInterface(new DefaultProvidedInterface(
+                    "external", String.class));
+        final Environment env1      = new Environment("env1");
+        final Environment env2      = new Environment("env2");
+
+        container.addComponent(env1);
+        container.addComponent(env2);
+
+        // Wrong external provided interface name
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectExternalProvided(container.getProvidedInterfaces()
+                        .get(0).getName() + "xx", "env1",
+                        env1.getProvidedInterfaces().get(0).getName());
+                }
+            }, SystemAssemblyException.class);
+
+        // Wrong provided interface name.
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectExternalProvided(container.getProvidedInterfaces()
+                        .get(0).getName(), "env1",
+                        env1.getProvidedInterfaces().get(0).getName() + "xx");
+                }
+            }, SystemAssemblyException.class);
+
+        // Wrong provided component
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+                @Override
+                public void run() throws Exception {
+                    container.connectExternalProvided(container.getProvidedInterfaces()
+                        .get(0).getName(), "env3",
+                        env1.getProvidedInterfaces().get(0).getName());
+                }
+            }, SystemAssemblyException.class);
+    }
+
+    private static class MyMultiple implements Serializable, Runnable {
+        @Override
+        public void run() {
+            // Empty
+        }
+    }
 }