(no commit message)
[utils] / system / general / src / test / java / org / wamblee / system / container / ContainerTest.java
index a7589fe46250eff9561c11ec987e1a52071e0f56..cbd623e9e963e3ba050552615905da069b455685 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 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.
@@ -35,711 +35,731 @@ import org.wamblee.system.core.SystemAssemblyException;
 import org.wamblee.test.AssertionUtils;
 import org.wamblee.test.EventTracker;
 
+/**
+ * 
+ * @author $author$
+ * @version $Revision$
+ */
 public class ContainerTest extends TestCase {
-
-       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);
-       }
+    private EventTracker<String> tracker;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        tracker = new EventTracker<String>();
+    }
+
+    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);
+
+            ignoredVariable(system);
+            ignoredVariable(system2);
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+
+        fail();
+    }
+
+    private static void ignoredVariable(Object aObject) {
+        // for findbugs.
+    }
+
+    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);
+
+        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);
+
+        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);
+    }
+
+    private static class MyMultiple implements Serializable, Runnable {
+        @Override
+        public void run() {
+            // Empty
+        }
+    }
 }