diff --git a/Modules/Core/ComponentInterface/ComponentBase.h b/Modules/Core/ComponentInterface/ComponentBase.h
index 3249b12a2c37cbaf8c8f2ebf0fa21f1d9b1adbd0..78da4c6aa435408dd277e716dac4cf1c8bd335d1 100644
--- a/Modules/Core/ComponentInterface/ComponentBase.h
+++ b/Modules/Core/ComponentInterface/ComponentBase.h
@@ -5,7 +5,10 @@ namespace elx
 {
   class ComponentBase {
   public:
+    virtual int ConnectFrom(const char *, ComponentBase*) { return 0; }; //= 0;
+  protected:
     virtual ~ComponentBase(){};
   };
+
 } // end namespace elx
 #endif // #define ComponentBase_h
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx
index b2118b1304592d7144c81045b89eeb918c9ecc52..0b8fac5cff5f5bcd7997bb52a99417f575236702 100644
--- a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx
+++ b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx
@@ -13,6 +13,35 @@ GDOptimizer3rdPartyComponent::~GDOptimizer3rdPartyComponent()
   delete this->MetricObject;
 }
 
+
+int GDOptimizer3rdPartyComponent::ConnectFrom(const char * interfacename, ComponentBase* other)
+{
+  //TODO write out as templated functionality:
+  if (std::strcmp(InterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get(), interfacename) == 0)
+  {
+    InterfaceAcceptor<MetricValueInterface>* acceptIF = static_cast<InterfaceAcceptor<MetricValueInterface>*> (this);
+    if (!acceptIF)
+    {
+      std::cout << InterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get() << " optimizer has no OptimizerValueInterface" << std::endl;
+    }
+    // connect value interfaces
+    acceptIF->Connect(other);
+    return 1; //success, assume only one interface listens interfacename
+  }
+  if (std::strcmp(InterfaceName<InterfaceAcceptor<MetricDerivativeInterface>>::Get(), interfacename) == 0)
+  {
+    InterfaceAcceptor<MetricDerivativeInterface>* acceptIF = static_cast<InterfaceAcceptor<MetricDerivativeInterface>*> (this);
+    if (!acceptIF)
+    {
+      std::cout << InterfaceName<InterfaceAcceptor<MetricDerivativeInterface>>::Get() << " optimizer has no OptimizerValueInterface" << std::endl;
+    }
+    // connect value interfaces
+    acceptIF->Connect(other);
+    return 1; //success, assume only one interface listens interfacename
+  }
+  return 0;
+}
+
 int GDOptimizer3rdPartyComponent::Set(MetricValueInterface* component)
 {
   this->MetricObject->SetMetricValueComponent(component);
diff --git a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h
index 8ff19a2f830845598b1974b59635a8a2f6a079a3..7addba7b1581a17eedbdc53b20d410bf987dd4ad 100644
--- a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h
+++ b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h
@@ -5,6 +5,7 @@
 #include "Interfaces.hxx"
 #include "Example3rdPartyCode.h"
 #include "Metric3rdPartyWrapper.h"
+#include <string.h>
 
 namespace elx
 {
@@ -15,6 +16,7 @@ namespace elx
     ~GDOptimizer3rdPartyComponent();
     Example3rdParty::GDOptimizer3rdParty* theImplementation;
     Metric3rdPartyWrapper* MetricObject;
+    virtual int ConnectFrom(const char *, ComponentBase*);
     int Set(MetricValueInterface*);
     int Set(MetricDerivativeInterface*);
     int Update();
diff --git a/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.cxx b/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.cxx
index cd797a94d9c1bb8855885e94c823528639cfacf8..16df9f8d380bf162d74216898cc798fad8a6962c 100644
--- a/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.cxx
+++ b/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.cxx
@@ -15,6 +15,23 @@ GDOptimizer4thPartyComponent::~GDOptimizer4thPartyComponent()
   delete this->MetricObject;
 }
 
+int GDOptimizer4thPartyComponent::ConnectFrom(const char * interfacename, ComponentBase* other)
+{
+  //TODO write out as templated functionality:
+  if (std::strcmp(InterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get(), interfacename) == 0)
+  {
+    InterfaceAcceptor<MetricValueInterface>* acceptIF = static_cast<InterfaceAcceptor<MetricValueInterface>*> (this);
+    if (!acceptIF)
+    {
+      std::cout << InterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get() << " optimizer has no OptimizerValueInterface" << std::endl;
+    }
+    // connect value interfaces
+    acceptIF->Connect(other);
+    return 1; //success, assume only one interface listens interfacename
+  }
+  return 0;
+}
+
 int GDOptimizer4thPartyComponent::Set(MetricValueInterface* component)
 {
   this->MetricObject->SetMetricValueComponent(component);
diff --git a/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.h b/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.h
index f65989491f24735b5cdc8c45eaafd445ff81eaf2..2e3a33d8643e1c7c889805560d2dbfe5a3a2b6b2 100644
--- a/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.h
+++ b/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.h
@@ -16,6 +16,7 @@ namespace elx
     ~GDOptimizer4thPartyComponent();
     Example4thParty::GDOptimizer4thParty* theImplementation;
     Metric4thPartyWrapper* MetricObject;
+    virtual int ConnectFrom(const char *, ComponentBase*);
     int Set(MetricValueInterface*);
     int Update();
   };
diff --git a/Modules/Core/ComponentInterface/Interfaces.hxx b/Modules/Core/ComponentInterface/Interfaces.hxx
index ee85ebeb5a9f79177973429ad385614beb47c22a..c74468bb241d66d4780e6c5bd3bad6ed6fa74c49 100644
--- a/Modules/Core/ComponentInterface/Interfaces.hxx
+++ b/Modules/Core/ComponentInterface/Interfaces.hxx
@@ -46,5 +46,74 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
     return 1;
   }
 
+
+// TEST
+template<class InterfaceT>
+class InterfaceProvider {
+public:
+  virtual int Set(InterfaceT*) {};
+private:
+};
+
+
+// Traits to get printable interface name
+// default implementation
+template <typename T>
+struct InterfaceName
+{
+  static const char* Get()
+  {
+    return typeid(T).name();
+  }
+};
+
+// a specialization for each type of those you want to support
+// and don't like the string returned by typeid
+template <>
+struct InterfaceName < MetricValueInterface >
+{
+  static const char* Get()
+  {
+    return "MetricValueInterface";
+  }
+};
+template <>
+struct InterfaceName < MetricDerivativeInterface >
+{
+  static const char* Get()
+  {
+    return "MetricDerivativeInterface";
+  }
+};
+template <>
+struct InterfaceName < OptimizerUpdateInterface >
+{
+  static const char* Get()
+  {
+    return "OptimizerUpdateInterface";
+  }
+};
+
+
+// partial specialization of InterfaceName
+template<template<typename> class TT, typename T1>
+struct InterfaceName < TT<T1> > {
+  static const char* Get()
+  {
+    return InterfaceName<T1>::Get();
+  }
+};
+
+
+template <typename T>
+struct AcceptorInterfaceName
+{
+  static const char* Get()
+  {
+    return InterfaceName<T>::Get();
+  }
+};
+
+
 } // end namespace elx
 #endif // #define Interfaces_hxx
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/componenthandshake.cxx b/Modules/Core/ComponentInterface/componenthandshake.cxx
index b7cb8fed865bec83d9efc199e627cd61ae5258b6..930b202813e5c9a7e39b94404d051e2a469c94df 100644
--- a/Modules/Core/ComponentInterface/componenthandshake.cxx
+++ b/Modules/Core/ComponentInterface/componenthandshake.cxx
@@ -8,8 +8,20 @@
 #include "SSDMetric4thPartyComponent.h"
 #include "GDOptimizer4thPartyComponent.h"
 
+
+
 using namespace elx;
   int main() {
+    {
+      std::cout << InterfaceName<MetricValueInterface>::Get() << std::endl;
+
+      std::cout << AcceptorInterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get() << std::endl;
+
+      std::cout << InterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get() << std::endl;
+      std::cout << InterfaceName<InterfaceProvider<MetricValueInterface>>::Get() << std::endl;
+
+      
+    }
     {
       /************ testing interface casts ***********
       * expected: ok
@@ -33,6 +45,8 @@ using namespace elx;
     GDOptimizer4thPartyComponent* tempOptimizer4p = new GDOptimizer4thPartyComponent();
     ComponentBase* optimizer4p = tempOptimizer4p; // type returned by our component factory
 
+    int success = optimizer4p->ConnectFrom("MetricValueInterface", metric4p);
+
     InterfaceAcceptor<MetricValueInterface>* opValIF = dynamic_cast<InterfaceAcceptor<MetricValueInterface>*> (optimizer4p);
     if (!opValIF)
     {