private ComponentGraph createComponentGraph() {
         ComponentGraph graph = new ComponentGraph();
         for (RequiredInterface req : getRequiredInterfaces()) {
-            graph.addRequiredInterface(req);
+            graph.addRequiredInterface(this, req);
         }
         for (Component comp : _components) {
             graph.addComponent(comp);
         }
         for (ProvidedInterface prov: getProvidedInterfaces()) { 
-            graph.addProvidedInterface(prov);
+            graph.addProvidedInterface(this, prov);
         }
 
         graph.addRestriction(_restriction);
 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- */ 
+ */
 package org.wamblee.system.graph.component;
 
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.wamblee.system.core.SystemAssemblyException;
 import org.wamblee.system.graph.Edge;
+import org.wamblee.system.graph.Graph;
 import org.wamblee.system.graph.Node;
 import org.wamblee.system.graph.Visitor;
 
 /**
  * Visitor that checks whether all required external interfaces of the container
- * are provided. 
+ * are provided.
+ * 
  * @author Erik Brakkee
- *
+ * 
  */
 public class CheckExternallyRequiredVisitor implements Visitor {
-    
-    public CheckExternallyRequiredVisitor() { 
-        // Empty.
+
+    private Log LOG = LogFactory.getLog(CheckExternallyRequiredVisitor.class);
+
+    private Graph _graph;
+
+    public CheckExternallyRequiredVisitor(Graph aGraph) {
+        _graph = aGraph;
     }
 
     @Override
 
     @Override
     public void visitNode(Node aNode) {
-        if ( aNode instanceof ExternalRequiredInterfaceNode) { 
-            ExternalRequiredInterfaceNode required = (ExternalRequiredInterfaceNode) aNode; 
-            if ( !required.getRequired().isOptional() && required.getRequired().getProvider() == null) { 
-                throw new SystemAssemblyException(aNode + ": External required interface is not provided");
+        if (aNode instanceof ExternalRequiredInterfaceNode) {
+            ExternalRequiredInterfaceNode required = (ExternalRequiredInterfaceNode) aNode;
+            if (!required.getRequired().isOptional()
+                    && required.getRequired().getProvider() == null) {
+                throw new SystemAssemblyException(aNode
+                        + ": External required interface is not provided");
+            }
+
+            List<Edge> edges = _graph.findIncoming(aNode);
+
+            if (edges.isEmpty()) {
+                LOG.warn(aNode + ": Superfluous required interface");
+            }
+            for (Edge edge : edges) {
+                Node from = edge.getFrom();
+                assert from instanceof RequiredInterfaceNode;
+                RequiredInterfaceNode reqNode = (RequiredInterfaceNode)from;
+                if (!reqNode.getRequired().isOptional()
+                        && required.getRequired().isOptional()) {
+                    throw new SystemAssemblyException(
+                            aNode
+                                    + ": externally required interface is optional but a corresponding internal required interface is mandatory: "
+                                    + reqNode);
+                }
             }
         }
     }
 
             RequiredInterfaceNode required = (RequiredInterfaceNode) aNode;
             List<Edge> edges = _graph.findOutgoing(aNode);
             if (edges.size() > 1) {
-                createDuplicateException("Multiple internal providers of interface found", aNode, edges);
+                createDuplicateException("Multiple providers of required interface found", aNode, edges);
             }
             if (edges.size() == 0 && !required.getRequired().isOptional()) {
                 throw new SystemAssemblyException(
                         aNode
                                 + ": mandatpory required interface not provided by other components started earlier");
             }
-        } else if ( aNode instanceof ProvidedInterfaceNode) { 
+        } else if ( aNode instanceof ExternalProvidedInterfaceNode) { 
             List<Edge> edges = _graph.findOutgoing(aNode); 
             if ( edges.size() > 1) { 
                 createDuplicateException("multiple internal matches for externally provided interface", aNode, edges);
 
 import org.wamblee.system.graph.Graph;
 import org.wamblee.system.graph.Node;
 
-
-// TODO info superfluous required interfaces
-// TODO check optional external required but mandatory internal.  
-
 /**
  * Represents a component graph and provides the bridge from the 
  * component model to a graph model. The graph model is easier
     /**
      * Constructs an empty component graph. 
      */
-    public ComponentGraph() { 
+    public ComponentGraph() {
         _restriction = new CompositeInterfaceRestriction(); 
     }
     
      * Adds an externally required interface of a container.  
      * This should be called before any components of the container are
      * added. 
+     * @param aComponent Component requiring the interface. 
      * @param aInterface Required interface. 
      */
-    public void addRequiredInterface(RequiredInterface aInterface) { 
-        addNode(new ExternalRequiredInterfaceNode(aInterface));
+    public void addRequiredInterface(Component aComponent, RequiredInterface aInterface) { 
+        addNode(new ExternalRequiredInterfaceNode(aComponent, aInterface));
     }
     
     /**
      * Adds an externally provided interface of a container.
-     * This should be called after all components of the container have been added.  
+     * This should be called after all components of the container have been added.
+     * @param aComponent Component providing the interface.   
      * @param aInterface Provided interface. 
      */
-    public void addProvidedInterface(ProvidedInterface aInterface) { 
-        addNode(new ExternalProvidedInterfaceNode(aInterface));
+    public void addProvidedInterface(Component aComponent, ProvidedInterface aInterface) { 
+        addNode(new ExternalProvidedInterfaceNode(aComponent, aInterface));
     }
     
     /**
         extend(new RequiredProvidedEdgeFactory());
         accept(new ApplyRestrictionsVisitor(this, _restriction));
         accept(new CheckRequiredProvidedMultiplicityVisitor(this));
-        accept(new CheckExternallyRequiredVisitor());
+        accept(new CheckExternallyRequiredVisitor(this)); 
         accept(new CheckExternallyProvidedVisitor(this));
         accept(new CheckStartupDependenciesVisitor(this));
     }
 
  */ 
 package org.wamblee.system.graph.component;
 
+import org.wamblee.system.core.Component;
 import org.wamblee.system.core.ProvidedInterface;
 import org.wamblee.system.graph.Node;
 
  */
 public class ExternalProvidedInterfaceNode implements Node {
 
+    private Component _component; 
     private ProvidedInterface _provided; 
     
-    public ExternalProvidedInterfaceNode(ProvidedInterface aProvided) { 
+    public ExternalProvidedInterfaceNode(Component aComponent, ProvidedInterface aProvided) {
+        _component = aComponent; 
         _provided = aProvided; 
     }
     
         return _provided.getName(); 
     }
     
+    public Component getComponent() {
+        return _component;
+    }
+    
     public ProvidedInterface getProvided() {
         return _provided;
     }
 
  */ 
 package org.wamblee.system.graph.component;
 
+import org.wamblee.system.core.Component;
 import org.wamblee.system.core.RequiredInterface;
 import org.wamblee.system.graph.Node;
 
  */
 public class ExternalRequiredInterfaceNode implements Node {
     
+    private Component _component;
     private RequiredInterface _required; 
 
-    public ExternalRequiredInterfaceNode(RequiredInterface aRequired) { 
+    public ExternalRequiredInterfaceNode(Component aComponent, RequiredInterface aRequired) {
+        _component = aComponent; 
         _required = aRequired; 
     }
     
         return _required.getName(); 
     }
     
+    public Component getComponent() {
+        return _component;
+    }
+    
     public RequiredInterface getRequired() {
         return _required;
     }
     
     @Override
     public String toString() {
-        return "EXTERNAL" + ":" + _required;
+        return _component.getQualifiedName() + ":" + _required;
     }
 }
 
                 .getProvidedInterfaces()[0]);
         container.getRequiredInterfaces()[1].setProvider(env
                 .getProvidedInterfaces()[1]);
-        container.start();
-        assertSame(env.getProvidedInterfaces()[0], container
-                .getRequiredInterfaces()[0].getProvider());
-        assertSame(env.getProvidedInterfaces()[1], container
-                .getRequiredInterfaces()[1].getProvider());
-        assertSame(env.getProvidedInterfaces()[0], application
-                .getRequiredInterfaces()[0].getProvider());
-        assertSame(env.getProvidedInterfaces()[1], application
-                .getRequiredInterfaces()[1].getProvider());
+        try {
+            container.start();
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+        fail();
     }
 
     public void testSealed() {
         top.addComponent(envcontainer).addComponent(appcontainer);
 
         top.start();
-        AssertionUtils.assertEquals(new String[] { "start.environment", "start.application" },
-                _tracker.getEvents(Thread.currentThread()).toArray(
-                        new String[0]));
+        AssertionUtils.assertEquals(new String[] { "start.environment",
+                "start.application" }, _tracker.getEvents(
+                Thread.currentThread()).toArray(new String[0]));
 
     }
 }