diff --git a/CMakeLists.txt b/CMakeLists.txt
index 28b724f9197d24f596c1407e22b9096bcdf09b32..131af57444895cdd68d6e693e866856b0dac2b8f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,6 +7,8 @@ cmake_minimum_required( VERSION 2.8 )
 # ---------------------------------------------------------------------
 project( Elastix )
 
+set( CMAKE_CXX_STANDARD 11 )
+
 # Place libraries and executables in the bin directory
 set( CMAKE_RUNTIME_OUTPUT_DIRECTORY
   "${CMAKE_BINARY_DIR}/bin"
diff --git a/Modules/Core/ComponentInterface/include/ComponentBase.h b/Modules/Core/ComponentInterface/include/ComponentBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..a84aef60d94f19902f13f0becf0ea9757c9bfac6
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/ComponentBase.h
@@ -0,0 +1,18 @@
+#ifndef ComponentBase_h
+#define ComponentBase_h
+
+#include <iostream>
+#include <cstring>
+namespace elx
+{
+  enum interfaceStatus { success, noaccepter, noprovider };
+
+  class ComponentBase {
+  public:
+    virtual interfaceStatus ConnectFrom(const char *, ComponentBase*) = 0;
+    virtual int ConnectFrom(ComponentBase*) = 0;
+  //protected:
+    virtual ~ComponentBase() {};
+  };
+} // end namespace elx
+#endif // #define ComponentBase_h
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/include/Example3rdPartyCode.h b/Modules/Core/ComponentInterface/include/Example3rdPartyCode.h
new file mode 100644
index 0000000000000000000000000000000000000000..6535a4f5bf916852fd5e530e606109b60b21690b
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/Example3rdPartyCode.h
@@ -0,0 +1,41 @@
+#ifndef Example3rdPartyCode_h
+#define Example3rdPartyCode_h
+
+#include <iostream>
+namespace Example3rdParty
+{
+
+  // test case: there are two (slightly) incompatible codebases (i.e. 3rd party and 4th party!), each with an optimizer object and a metric object. 
+  // goal: make elastix components of all objects and define a handshake that checks if connections can be made.
+
+  /*************** below: example implementations of 3rd and 4th party code base (assume we cannot change that) *********************/
+
+  class Metric3rdPartyBase{
+  public:
+    virtual int GetValue() = 0;
+    virtual int GetDerivative() = 0;
+  };
+
+  class Optimizer3rdPartyBase{
+  public:
+    virtual int SetMetric(Metric3rdPartyBase*) = 0;
+    virtual int Optimize() = 0;
+  protected:
+    Metric3rdPartyBase* theMetric;
+  };
+
+  class SSDMetric3rdParty : public Metric3rdPartyBase {
+  public:
+    virtual int GetValue() { return 1; };
+    virtual int GetDerivative() { return 2; };
+  };
+
+  class GDOptimizer3rdParty : public Optimizer3rdPartyBase {
+  public:
+    GDOptimizer3rdParty();
+    ~GDOptimizer3rdParty();
+    virtual int SetMetric(Metric3rdPartyBase*);
+    virtual int Optimize();
+  };
+} // end namespave Example3rdParty
+#endif // #define Example3rdPartyCode_h
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/include/Example4thPartyCode.h b/Modules/Core/ComponentInterface/include/Example4thPartyCode.h
new file mode 100644
index 0000000000000000000000000000000000000000..d3701f96a80f546cbe099761fc61b55727274949
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/Example4thPartyCode.h
@@ -0,0 +1,40 @@
+#ifndef Example4thPartyCode_h
+#define Example4thPartyCode_h
+
+#include <iostream>
+
+namespace Example4thParty
+{
+	
+// test case: there are two (slightly) incompatible codebases (i.e. 3rd party and 4th party!), each with an optimizer object and a metric object. 
+// goal: make elastix components of all objects and define a handshake that checks if connections can be made.
+
+/*************** below: example implementations of 3rd and 4th party code base (assume we cannot change that) *********************/
+
+class Metric4thPartyBase{
+public:
+  virtual int GetCost() = 0; // with different naming convention than 3rd party
+};
+
+class Optimizer4thPartyBase{
+public:
+  virtual int SetMetric(Metric4thPartyBase*) = 0;
+  virtual int DoOptimization() = 0; // with different naming convention than 3rd party
+protected:
+  Metric4thPartyBase* theMetric;
+};
+
+class SSDMetric4thParty : public Metric4thPartyBase {
+public:
+  virtual int GetCost() { return 3; };
+};
+
+class GDOptimizer4thParty : public Optimizer4thPartyBase {
+public:
+  GDOptimizer4thParty();
+  ~GDOptimizer4thParty();
+  virtual int SetMetric(Metric4thPartyBase*);
+  virtual int DoOptimization();
+};
+} // end namespave Example4thParty
+#endif // #define Example4thPartyCode_h
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/include/GDOptimizer3rdPartyComponent.h b/Modules/Core/ComponentInterface/include/GDOptimizer3rdPartyComponent.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d281e9b9fa7541e14721693433c8f307937578a
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/GDOptimizer3rdPartyComponent.h
@@ -0,0 +1,30 @@
+#ifndef GDOptimizer3rdPartyComponent_h
+#define GDOptimizer3rdPartyComponent_h
+
+#include "ComponentBase.h"
+#include "Interfaces.hxx"
+#include "Example3rdPartyCode.h"
+#include "Metric3rdPartyWrapper.h"
+#include <string.h>
+
+namespace elx
+{
+
+  class GDOptimizer3rdPartyComponent : 
+    public Implements<
+      Accepting< MetricValueInterface, MetricDerivativeInterface >,
+      Providing< OptimizerUpdateInterface>
+    >
+  {
+  public:
+    GDOptimizer3rdPartyComponent();
+    virtual ~GDOptimizer3rdPartyComponent();
+    Example3rdParty::GDOptimizer3rdParty* theImplementation;
+    Metric3rdPartyWrapper* MetricObject;
+    //virtual int ConnectFrom(const char *, ComponentBase*);
+    int Set(MetricValueInterface*);
+    int Set(MetricDerivativeInterface*);
+    int Update();
+  };
+} //end namespace elx
+#endif // #define GDOptimizer3rdPartyComponent_h
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/include/GDOptimizer4thPartyComponent.h b/Modules/Core/ComponentInterface/include/GDOptimizer4thPartyComponent.h
new file mode 100644
index 0000000000000000000000000000000000000000..eff1bb78cd856c4f9b6ae6088c2b5d555fb05077
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/GDOptimizer4thPartyComponent.h
@@ -0,0 +1,30 @@
+#ifndef GDOptimizer4thPartyComponent_h
+#define GDOptimizer4thPartyComponent_h
+
+#include "ComponentBase.h"
+#include "Interfaces.hxx"
+#include "Example4thPartyCode.h"
+#include "Metric4thPartyWrapper.h"
+
+namespace elx
+{
+  // wrapping into components: 
+  class GDOptimizer4thPartyComponent : 
+    public Implements <
+    Accepting< MetricValueInterface >,
+    Providing < OptimizerUpdateInterface >
+    >
+
+  {
+  public:
+    GDOptimizer4thPartyComponent();
+    virtual ~GDOptimizer4thPartyComponent();
+    Example4thParty::GDOptimizer4thParty* theImplementation;
+    Metric4thPartyWrapper* MetricObject;
+    //virtual int ConnectFrom(const char *, ComponentBase*);
+    int Set(MetricValueInterface*);
+    int Update();
+  };
+
+} //end namespace elx
+#endif // #define GDOptimizer4thPartyComponent_h
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/include/InterfaceTraits.h b/Modules/Core/ComponentInterface/include/InterfaceTraits.h
new file mode 100644
index 0000000000000000000000000000000000000000..5dd03ec37bccab68b6be2b1450cb6d588532d0e5
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/InterfaceTraits.h
@@ -0,0 +1,69 @@
+#ifndef InterfaceTraits_h
+#define InterfaceTraits_h
+
+#include "Interfaces.h"
+
+namespace elx
+{
+// 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 InterfaceTraits_h
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/include/Interfaces.h b/Modules/Core/ComponentInterface/include/Interfaces.h
new file mode 100644
index 0000000000000000000000000000000000000000..281d763d3ebbaf8608afb70fd02bdf98b0b9ce57
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/Interfaces.h
@@ -0,0 +1,78 @@
+#ifndef Interfaces_h
+#define Interfaces_h
+
+#include "ComponentBase.h"
+#include "InterfaceTraits.h"
+#include <typeinfo>
+
+namespace elx
+{
+// Define the providing interfaces abstractly
+class MetricDerivativeInterface {
+  public:
+    virtual int GetDerivative() = 0;
+};
+
+class MetricValueInterface {
+  public:
+    virtual int GetValue() = 0;
+};
+
+class OptimizerUpdateInterface {
+public:
+  virtual int Update() = 0;
+};
+
+// Define the accepting interfaces as templated by the providing interface
+
+template<class InterfaceT>
+class InterfaceAcceptor {
+public:
+
+  // Set() is called by a succesfull Connect()
+  // The implementation of Set() must be provided by component developers. 
+  virtual int Set(InterfaceT*) = 0; 
+
+  // Connect tries to connect this accepting interface with all interfaces of the provider component.
+  int Connect(ComponentBase*); 
+
+private:
+  bool isSet;
+};
+
+template<typename ... RestInterfaces>
+class Accepting
+{
+  public:
+    interfaceStatus ConnectFromImpl(const char *, ComponentBase*) { return interfaceStatus::noaccepter; }; //no interface called interfacename ;
+    int ConnectFromImpl(ComponentBase*) { return 0; }; //Empty RestInterfaces does 0 successful connects ;
+};
+
+template<typename FirstInterface, typename ... RestInterfaces>
+class Accepting<FirstInterface, RestInterfaces... > : public InterfaceAcceptor<FirstInterface>, public Accepting< RestInterfaces ... >
+{
+public:
+  interfaceStatus ConnectFromImpl(const char *, ComponentBase*);
+  int ConnectFromImpl(ComponentBase*);
+};
+
+template<typename... Interfaces>
+class Providing : public Interfaces...
+{
+};
+
+template<typename AcceptingInterfaces, typename ProvidingInterfaces>
+class Implements : public AcceptingInterfaces, public ProvidingInterfaces, public ComponentBase
+{
+  public:
+    virtual interfaceStatus ConnectFrom(const char *, ComponentBase*);
+    virtual int ConnectFrom(ComponentBase*);
+};
+
+} // end namespace elx
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "Interfaces.hxx"
+#endif
+
+#endif // #define Interfaces_h
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/include/Interfaces.hxx b/Modules/Core/ComponentInterface/include/Interfaces.hxx
new file mode 100644
index 0000000000000000000000000000000000000000..cade1ce157abcb8b48165d0993ff80785a50d2dd
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/Interfaces.hxx
@@ -0,0 +1,71 @@
+#ifndef Interfaces_hxx
+#define Interfaces_hxx
+
+#include "InterfaceTraits.h"
+namespace elx
+{
+template<class InterfaceT>
+int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
+
+  InterfaceT* providerInterface = dynamic_cast<InterfaceT*> (providerComponent);
+  if (!providerInterface)
+  {
+    std::cout << "providerComponent does not have required " << InterfaceName < InterfaceT >::Get() << std::endl;
+    return 0;
+  }
+  // connect value interfaces
+  this->Set(providerInterface); // due to the input argument being uniquely defined in the multiple inheritance tree, all versions of Set() are accessible at component level
+  return 1;
+}
+
+template<typename AcceptingInterfaces, typename ProvidingInterfaces>
+interfaceStatus Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(const char * interfacename, ComponentBase* other)
+{
+  return AcceptingInterfaces::ConnectFromImpl(interfacename, other);
+}
+
+template<typename AcceptingInterfaces, typename ProvidingInterfaces>
+int Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(ComponentBase* other)
+{
+  return AcceptingInterfaces::ConnectFromImpl(other);
+}
+
+template<typename FirstInterface, typename ... RestInterfaces>
+interfaceStatus Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(const char * interfacename, ComponentBase* other)
+{
+  // does our component have an accepting interface called interfacename? 
+  if (0 ==std::strcmp(InterfaceName<InterfaceAcceptor<FirstInterface>>::Get(), interfacename))
+  {
+    // static_cast always succeeds since we know via the template arguments of the component which InterfaceAcceptors its base classes are.
+    InterfaceAcceptor<FirstInterface>* acceptIF = static_cast<InterfaceAcceptor<FirstInterface>*> (this);
+
+    // See if the other component has the right interface and try to connect them
+    if (1 == acceptIF->Connect(other))
+    {
+      //success. By terminating this function, we assume only one interface listens to interfacename and that one connection with the other component can be made by this name
+      return interfaceStatus::success;
+    }
+    else
+    {
+      // interfacename was found, but other component doesn't match
+      return interfaceStatus::noprovider;
+    }
+  }
+  return Accepting< RestInterfaces ... >::ConnectFromImpl(interfacename, other);
+}
+
+template<typename FirstInterface, typename ... RestInterfaces>
+int Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(ComponentBase* other)
+{
+  // static_cast always succeeds since we know via the template arguments of the component which InterfaceAcceptors its base classes are.
+  InterfaceAcceptor<FirstInterface>* acceptIF = static_cast<InterfaceAcceptor<FirstInterface>*> (this);
+
+  // See if the other component has the right interface and try to connect them
+  // count the number of successes
+  return acceptIF->Connect(other) + Accepting< RestInterfaces ... >::ConnectFromImpl(other);
+}
+
+} // end namespace elx
+
+
+#endif // #define Interfaces_hxx
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/include/Metric3rdPartyWrapper.h b/Modules/Core/ComponentInterface/include/Metric3rdPartyWrapper.h
new file mode 100644
index 0000000000000000000000000000000000000000..6612b04e15862cf04e0e2e1fbd8ec8dbc5f2c44f
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/Metric3rdPartyWrapper.h
@@ -0,0 +1,20 @@
+#ifndef Metric3rdPartyWrapper_h
+#define Metric3rdPartyWrapper_h
+
+#include "Example3rdPartyCode.h"
+#include "Interfaces.hxx"
+namespace elx
+{
+// An Optimizer3rdParty expects that Metric3rdParty will be set as input. All accepted interfaces by the Optimizer3rdPartyCompoment will be delegated to the Metric3rdPartyWrapper object.
+  class Metric3rdPartyWrapper : public Example3rdParty::Metric3rdPartyBase  {
+public:
+  void SetMetricValueComponent(MetricValueInterface*);
+  void SetMetricDerivativeComponent(MetricDerivativeInterface*);
+  virtual int GetValue();
+  virtual int GetDerivative();
+private:
+  MetricValueInterface* metricval;
+  MetricDerivativeInterface* metricderiv;
+};
+} // end namespace elx
+#endif // #define Metric3rdPartyWrapper_h
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/include/Metric4thPartyWrapper.h b/Modules/Core/ComponentInterface/include/Metric4thPartyWrapper.h
new file mode 100644
index 0000000000000000000000000000000000000000..1a481281dec62a18df619ec497bb76c3fb406c0d
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/Metric4thPartyWrapper.h
@@ -0,0 +1,17 @@
+#ifndef Metric4thPartyWrapper_h
+#define Metric4thPartyWrapper_h
+
+#include "Example4thPartyCode.h"
+#include "Interfaces.hxx"
+namespace elx
+{
+// An Optimizer4thParty expects that Metric4thParty will be set as input. All accepted interfaces by the Optimizer4thPartyCompoment will be delegated to the Metric4thPartyWrapper object.
+  class Metric4thPartyWrapper : public Example4thParty::Metric4thPartyBase  {
+public:
+  void SetMetricValueComponent(MetricValueInterface*);
+  virtual int GetCost();
+private:
+  MetricValueInterface* metricval;
+};
+} // end namespace elx
+#endif // #define Metric3rdPartyWrapper_h
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/include/SSDMetric3rdPartyComponent.h b/Modules/Core/ComponentInterface/include/SSDMetric3rdPartyComponent.h
new file mode 100644
index 0000000000000000000000000000000000000000..860398a559b4862de5c5a9bc923e669b652b8f04
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/SSDMetric3rdPartyComponent.h
@@ -0,0 +1,25 @@
+#ifndef SSDMetric3rdPartyComponent_h
+#define SSDMetric3rdPartyComponent_h
+
+#include "ComponentBase.h"
+#include "Interfaces.hxx"
+#include "Example3rdPartyCode.h"
+
+namespace elx
+{
+  // SSDMetric3rdPartyComponent provides a value and a derivative
+  class SSDMetric3rdPartyComponent : 
+    public Implements<
+    Accepting<>,
+    Providing< MetricDerivativeInterface, MetricValueInterface>
+    >
+  {
+  public:
+    SSDMetric3rdPartyComponent();
+    virtual ~SSDMetric3rdPartyComponent();
+    Example3rdParty::SSDMetric3rdParty* theImplementation;
+    int GetValue();
+    int GetDerivative();
+  };
+} //end namespace elx
+#endif // #define SSDMetric3rdPartyComponent_h
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/include/SSDMetric4thPartyComponent.h b/Modules/Core/ComponentInterface/include/SSDMetric4thPartyComponent.h
new file mode 100644
index 0000000000000000000000000000000000000000..c07ff0abce595d7f55e6dda9c8aaaed38d19237c
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/SSDMetric4thPartyComponent.h
@@ -0,0 +1,24 @@
+#ifndef SSDMetric4thPartyComponent_h
+#define SSDMetric4thPartyComponent_h
+
+#include "ComponentBase.h"
+#include "Interfaces.hxx"
+#include "Example4thPartyCode.h"
+
+namespace elx
+{
+  // SSDMetric4thPartyComponent provides only a value and not a derivative
+  class SSDMetric4thPartyComponent : 
+    public Implements<
+    Accepting<>,
+    Providing< MetricValueInterface>
+    >
+  {
+  public:
+    SSDMetric4thPartyComponent();
+    virtual ~SSDMetric4thPartyComponent();
+    Example4thParty::SSDMetric4thParty* theImplementation;
+    int GetValue();
+  };
+} //end namespace elx
+#endif // #define SSDMetric4thPartyComponent_h
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/src/Example3rdPartyCode.cxx b/Modules/Core/ComponentInterface/src/Example3rdPartyCode.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ef3f9d660296fc1475fd3cac8a1b915e024c8e9b
--- /dev/null
+++ b/Modules/Core/ComponentInterface/src/Example3rdPartyCode.cxx
@@ -0,0 +1,26 @@
+#include "Example3rdPartyCode.h"
+namespace Example3rdParty
+{
+GDOptimizer3rdParty::GDOptimizer3rdParty()
+{
+  this->theMetric = nullptr;
+}
+GDOptimizer3rdParty::~GDOptimizer3rdParty()
+{
+}
+int GDOptimizer3rdParty::SetMetric(Metric3rdPartyBase* metric)
+{
+  this->theMetric = metric;
+  return 0;
+}
+int GDOptimizer3rdParty::Optimize()
+{
+  if (this->theMetric != nullptr)
+  {
+    std::cout << "GDOptimizer3rdParty->Optimize():" << std::endl;
+    std::cout << "  theMetric->GetValue():" << theMetric->GetValue() << std::endl;
+    std::cout << "  theMetric->GetDerivative():" << theMetric->GetDerivative() << std::endl;
+  }
+  return 0;
+}
+} // end namespace Example3rdParty
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/src/Example4thPartyCode.cxx b/Modules/Core/ComponentInterface/src/Example4thPartyCode.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..56cb20048bee40700c3bcc3c19b535149fe4c313
--- /dev/null
+++ b/Modules/Core/ComponentInterface/src/Example4thPartyCode.cxx
@@ -0,0 +1,25 @@
+#include "Example4thPartyCode.h"
+namespace Example4thParty
+{
+GDOptimizer4thParty::GDOptimizer4thParty()
+{
+  this->theMetric = nullptr;
+}
+GDOptimizer4thParty::~GDOptimizer4thParty()
+{
+}
+int GDOptimizer4thParty::SetMetric(Metric4thPartyBase* metric)
+{
+  this->theMetric = metric;
+  return 0;
+}
+int GDOptimizer4thParty::DoOptimization()
+{
+  if (this->theMetric != nullptr)
+  {
+    std::cout << "GDOptimizer4thParty->DoOptimization():" << std::endl;
+    std::cout << "  theMetric->GetCost():" << theMetric->GetCost() << std::endl;
+  }
+  return 0;
+}
+} // end namespace Example4thParty
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/src/GDOptimizer3rdPartyComponent.cxx b/Modules/Core/ComponentInterface/src/GDOptimizer3rdPartyComponent.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3f0e0db01c83d6a4f24d67490df5a12f0a9a1555
--- /dev/null
+++ b/Modules/Core/ComponentInterface/src/GDOptimizer3rdPartyComponent.cxx
@@ -0,0 +1,32 @@
+#include "GDOptimizer3rdPartyComponent.h"
+
+namespace elx
+{
+GDOptimizer3rdPartyComponent::GDOptimizer3rdPartyComponent()
+{
+  this->theImplementation = new Example3rdParty::GDOptimizer3rdParty();
+  this->MetricObject = new Metric3rdPartyWrapper();
+}
+GDOptimizer3rdPartyComponent::~GDOptimizer3rdPartyComponent()
+{
+  delete this->theImplementation;
+  delete this->MetricObject;
+}
+
+
+int GDOptimizer3rdPartyComponent::Set(MetricValueInterface* component)
+{
+  this->MetricObject->SetMetricValueComponent(component);
+  return 0;
+}
+int GDOptimizer3rdPartyComponent::Set(MetricDerivativeInterface* component)
+{
+  this->MetricObject->SetMetricDerivativeComponent(component);
+  return 0;
+}
+int GDOptimizer3rdPartyComponent::Update()
+{
+  this->theImplementation->SetMetric(this->MetricObject);
+  return this->theImplementation->Optimize(); // 3rd party specific call
+}
+} //end namespace elx
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/src/GDOptimizer4thPartyComponent.cxx b/Modules/Core/ComponentInterface/src/GDOptimizer4thPartyComponent.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..cd797a94d9c1bb8855885e94c823528639cfacf8
--- /dev/null
+++ b/Modules/Core/ComponentInterface/src/GDOptimizer4thPartyComponent.cxx
@@ -0,0 +1,29 @@
+#include "GDOptimizer4thPartyComponent.h"
+
+namespace elx
+{
+
+GDOptimizer4thPartyComponent::GDOptimizer4thPartyComponent()
+{
+  this->theImplementation = new Example4thParty::GDOptimizer4thParty();
+  this->MetricObject = new Metric4thPartyWrapper();
+}
+
+GDOptimizer4thPartyComponent::~GDOptimizer4thPartyComponent()
+{
+  delete this->theImplementation;
+  delete this->MetricObject;
+}
+
+int GDOptimizer4thPartyComponent::Set(MetricValueInterface* component)
+{
+  this->MetricObject->SetMetricValueComponent(component);
+  return 0;
+}
+
+int GDOptimizer4thPartyComponent::Update()
+{
+  this->theImplementation->SetMetric(this->MetricObject);
+  return this->theImplementation->DoOptimization(); // 4th party specific call
+}
+} //end namespace elx
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/src/Metric3rdPartyWrapper.cxx b/Modules/Core/ComponentInterface/src/Metric3rdPartyWrapper.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..18feaa555add72667d1d1a8256156ed77ef46e96
--- /dev/null
+++ b/Modules/Core/ComponentInterface/src/Metric3rdPartyWrapper.cxx
@@ -0,0 +1,24 @@
+#include "Metric3rdPartyWrapper.h"
+
+namespace elx
+{
+void Metric3rdPartyWrapper::SetMetricValueComponent(MetricValueInterface* metricValueComponent)
+{
+  this->metricval = metricValueComponent;
+}
+
+int Metric3rdPartyWrapper::GetValue()
+{
+  return this->metricval->GetValue();
+}
+
+void Metric3rdPartyWrapper::SetMetricDerivativeComponent(MetricDerivativeInterface* metricDerivativeComponent)
+{
+  this->metricderiv = metricDerivativeComponent;
+}
+
+int Metric3rdPartyWrapper::GetDerivative()
+{
+  return this->metricderiv->GetDerivative();
+}
+} // end namespace elx
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/src/Metric4thPartyWrapper.cxx b/Modules/Core/ComponentInterface/src/Metric4thPartyWrapper.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0bda72bbbad99aa4d6ae5ba3685f317d695dd414
--- /dev/null
+++ b/Modules/Core/ComponentInterface/src/Metric4thPartyWrapper.cxx
@@ -0,0 +1,15 @@
+#include "Metric4thPartyWrapper.h"
+
+namespace elx
+{
+void Metric4thPartyWrapper::SetMetricValueComponent(MetricValueInterface* metricValueComponent)
+{
+  this->metricval = metricValueComponent;
+}
+
+int Metric4thPartyWrapper::GetCost()
+{
+  return this->metricval->GetValue();
+}
+
+} // end namespace elx
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/src/SSDMetric3rdPartyComponent.cxx b/Modules/Core/ComponentInterface/src/SSDMetric3rdPartyComponent.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c4bc8260ebdd4aa0dba97b14859dfcfb837d0019
--- /dev/null
+++ b/Modules/Core/ComponentInterface/src/SSDMetric3rdPartyComponent.cxx
@@ -0,0 +1,22 @@
+#include "SSDMetric3rdPartyComponent.h"
+namespace elx
+{
+SSDMetric3rdPartyComponent::SSDMetric3rdPartyComponent()
+{
+  this->theImplementation = new Example3rdParty::SSDMetric3rdParty();
+}
+SSDMetric3rdPartyComponent::~SSDMetric3rdPartyComponent()
+{
+  delete this->theImplementation; 
+}
+
+int SSDMetric3rdPartyComponent::GetDerivative()
+{
+  return this->theImplementation->GetDerivative();
+};
+
+int SSDMetric3rdPartyComponent::GetValue()
+{
+  return this->theImplementation->GetValue();
+};
+} //end namespace elx
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/src/SSDMetric4thPartyComponent.cxx b/Modules/Core/ComponentInterface/src/SSDMetric4thPartyComponent.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..de00af4de98fdc8b30c74a72d30ee324b90de619
--- /dev/null
+++ b/Modules/Core/ComponentInterface/src/SSDMetric4thPartyComponent.cxx
@@ -0,0 +1,18 @@
+#include "SSDMetric4thPartyComponent.h"
+namespace elx
+{
+
+SSDMetric4thPartyComponent::SSDMetric4thPartyComponent()
+{
+  this->theImplementation = new Example4thParty::SSDMetric4thParty();
+}
+SSDMetric4thPartyComponent::~SSDMetric4thPartyComponent()
+{
+  delete this->theImplementation;
+}
+
+int SSDMetric4thPartyComponent::GetValue()
+{
+  return this->theImplementation->GetCost(); // translate method name
+};
+} //end namespace elx
\ No newline at end of file
diff --git a/Modules/Core/ComponentInterface/src/componenthandshake.cxx b/Modules/Core/ComponentInterface/src/componenthandshake.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..87492b3421751b307d47297914f09912b6027097
--- /dev/null
+++ b/Modules/Core/ComponentInterface/src/componenthandshake.cxx
@@ -0,0 +1,147 @@
+#include <iostream>
+
+// test case: Assume there are two (slightly) incompatible codebases (i.e. 3rd party and 4th! party), each with an optimizer object and a metric object. The example classes of 3rd and 4th party code bases cannot be changed, but the wrapping is in our control.
+// goal: make elastix components of all objects and define a handshake that checks if connections can be made.
+
+#include "SSDMetric3rdPartyComponent.h"
+#include "GDOptimizer3rdPartyComponent.h"
+#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
+      */
+      SSDMetric3rdPartyComponent* tempmetric3p = new SSDMetric3rdPartyComponent();
+      ComponentBase* metric3p = tempmetric3p;
+
+      MetricValueInterface* valIF = dynamic_cast<MetricValueInterface*> (metric3p);
+      std::cout << valIF->GetValue() << std::endl;
+
+      MetricDerivativeInterface* derIF = dynamic_cast<MetricDerivativeInterface*> (metric3p);
+      std::cout << derIF->GetDerivative() << std::endl;
+    }
+    /************ Connect metric4p to optimizer4p ***********
+    * expected: ok
+    */
+  {
+    SSDMetric4thPartyComponent* tempmetric4p = new SSDMetric4thPartyComponent();
+    ComponentBase* metric4p = tempmetric4p; // type returned by our component factory
+
+    GDOptimizer4thPartyComponent* tempOptimizer4p = new GDOptimizer4thPartyComponent();
+    ComponentBase* optimizer4p = tempOptimizer4p; // type returned by our component factory
+
+    interfaceStatus IFstatus = optimizer4p->ConnectFrom("MetricValueInterface", metric4p);
+
+    InterfaceAcceptor<MetricValueInterface>* opValIF = dynamic_cast<InterfaceAcceptor<MetricValueInterface>*> (optimizer4p);
+    if (!opValIF)
+    {
+      std::cout << "optimizer4p has no OptimizerValueInterface" << std::endl;
+    }
+
+    // connect value interfaces
+    opValIF->Connect(metric4p);
+
+    OptimizerUpdateInterface* opUpdIF = dynamic_cast<OptimizerUpdateInterface*> (optimizer4p);
+    if (!opValIF)
+    {
+      std::cout << "optimizer4p has no OptimizerUpdateInterface" << std::endl;
+    }
+
+    // Update the optimizer component 
+    opUpdIF->Update();
+  }
+  /************ Connect metric3p to optimizer4p ***********
+  * expected: ok
+  * optimizer4p will only use/have access to the GetValue interface of metric3p
+  */
+  {
+    SSDMetric3rdPartyComponent* tempmetric3p = new SSDMetric3rdPartyComponent();
+    ComponentBase* metric3p = tempmetric3p; // type returned by our component factory
+
+    GDOptimizer4thPartyComponent* tempOptimizer4p = new GDOptimizer4thPartyComponent();
+    ComponentBase* optimizer4p = tempOptimizer4p; // type returned by our component factory
+
+    InterfaceAcceptor<MetricValueInterface>* opValIF = dynamic_cast<InterfaceAcceptor<MetricValueInterface>*> (optimizer4p);
+    if (!opValIF)
+    {
+      std::cout << "optimizer4p has no OptimizerValueInterface" << std::endl;
+    }
+
+    // connect value interfaces
+    if (!opValIF->Connect(metric3p))
+    {
+      std::cout << "metric3p cannot connect to optimizer4p by ValueInterface" << std::endl;
+    }
+
+    OptimizerUpdateInterface* opUpdIF = dynamic_cast<OptimizerUpdateInterface*> (optimizer4p);
+    if (!opValIF)
+    {
+      std::cout << "optimizer4p has no OptimizerUpdateInterface" << std::endl;
+    }
+
+    // Update the optimizer component 
+    opUpdIF->Update();
+  }
+  /************ Connect metric4p to optimizer3p ***********
+  * expected: fail
+  * optimizer3p needs a metric with GetDerivative which metric4p doesn't have
+  */
+  {
+    SSDMetric4thPartyComponent* tempmetric4p = new SSDMetric4thPartyComponent();
+    ComponentBase* metric4p = tempmetric4p; // type returned by our component factory
+
+    GDOptimizer3rdPartyComponent* tempOptimizer3p = new GDOptimizer3rdPartyComponent();
+    ComponentBase* optimizer3p = tempOptimizer3p; // type returned by our component factory
+
+    InterfaceAcceptor<MetricValueInterface>* opValIF = dynamic_cast<InterfaceAcceptor<MetricValueInterface>*> (optimizer3p);
+    if (!opValIF)
+    {
+      std::cout << "optimizer3p has no OptimizerValueInterface" << std::endl;
+    }
+
+    // connect value interfaces
+    if (!opValIF->Connect(metric4p))
+    {
+      std::cout << "metric4p cannot connect to optimizer3p by ValueInterface" << std::endl;
+    }
+
+    //opValIF->Set(tempmetric4p);
+
+    InterfaceAcceptor<MetricDerivativeInterface>* opDerivIF = dynamic_cast<InterfaceAcceptor<MetricDerivativeInterface>*> (optimizer3p);
+    if (!opDerivIF)
+    {
+      std::cout << "optimizer3p has no OptimizerDerivativeInterface" << std::endl;
+    }
+    // connect derivative interfaces
+    if (!opDerivIF->Connect(metric4p))
+    {
+      std::cout << "metric4p cannot connect to optimizer3p by DerivativeInterface" << std::endl;
+    }
+
+
+    OptimizerUpdateInterface* opUpdIF = dynamic_cast<OptimizerUpdateInterface*> (optimizer3p);
+    if (!opValIF)
+    {
+      std::cout << "optimizer3p has no OptimizerUpdateInterface" << std::endl;
+    }
+
+    // Update the optimizer component 
+    // opUpdIF->Update(); // will fail since the metric does'nt have GetDerivative()
+  }
+  return 0;
+  }
diff --git a/Modules/Core/elxModuleCore.cmake b/Modules/Core/elxModuleCore.cmake
index 22b0e39670593db36c4d6cd1553bf233a05625d4..8e5e3e2dfbc60ffb02fc194444791290f73f169a 100644
--- a/Modules/Core/elxModuleCore.cmake
+++ b/Modules/Core/elxModuleCore.cmake
@@ -5,6 +5,7 @@ set( ${MODULE}_INCLUDE_DIRS
   ${${MODULE}_SOURCE_DIR}/Common/include
   ${${MODULE}_SOURCE_DIR}/Blueprints/include
   ${${MODULE}_SOURCE_DIR}/Install/include
+  ${${MODULE}_SOURCE_DIR}/ComponentInterface/include
 )
 
 # Export libraries
@@ -15,8 +16,17 @@ set( ${MODULE}_LIBRARIES
 # Module source files
 set( ${MODULE}_SOURCE_FILES
   ${${MODULE}_SOURCE_DIR}/Blueprints/src/elxBlueprint.cxx
+  ${${MODULE}_SOURCE_DIR}/ComponentInterface/src/Example3rdPartyCode.cxx
+  ${${MODULE}_SOURCE_DIR}/ComponentInterface/src/Example4thPartyCode.cxx
+  ${${MODULE}_SOURCE_DIR}/ComponentInterface/src/GDOptimizer3rdPartyComponent.cxx
+  ${${MODULE}_SOURCE_DIR}/ComponentInterface/src/GDOptimizer4thPartyComponent.cxx
+  ${${MODULE}_SOURCE_DIR}/ComponentInterface/src/Metric3rdPartyWrapper.cxx
+  ${${MODULE}_SOURCE_DIR}/ComponentInterface/src/Metric4thPartyWrapper.cxx
+  ${${MODULE}_SOURCE_DIR}/ComponentInterface/src/SSDMetric3rdPartyComponent.cxx
+  ${${MODULE}_SOURCE_DIR}/ComponentInterface/src/SSDMetric4thPartyComponent.cxx
 )
 
+
 # Compile library
 
 add_library( ${MODULE} STATIC "${${MODULE}_SOURCE_FILES}" )
diff --git a/Testing/Unit/CMakeLists.txt b/Testing/Unit/CMakeLists.txt
index 1c5e579fe9afcd8052fd6994699df0987da404cd..2186fe7715fd5279d4dcc6a14c2f4ae0c6d06086 100644
--- a/Testing/Unit/CMakeLists.txt
+++ b/Testing/Unit/CMakeLists.txt
@@ -7,6 +7,7 @@ set( ElastixUnitTestFilenames
   elxExampleUnitTest.cxx
   elxBlueprintTest.cxx
   elxComponentFactoryTest.cxx
+  elxComponentInterfaceTest.cxx
 )         
 
 
diff --git a/Testing/Unit/elxComponentInterfaceTest.cxx b/Testing/Unit/elxComponentInterfaceTest.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..43e2b6ee798b8a496fd9fc5bbcee4674d18bd692
--- /dev/null
+++ b/Testing/Unit/elxComponentInterfaceTest.cxx
@@ -0,0 +1,116 @@
+#include "SSDMetric3rdPartyComponent.h"
+#include "GDOptimizer3rdPartyComponent.h"
+#include "SSDMetric4thPartyComponent.h"
+#include "GDOptimizer4thPartyComponent.h"
+
+#include "gtest/gtest.h"
+
+namespace elx {
+
+class InterfaceTest : public ::testing::Test {
+public:
+
+  virtual void SetUp() {
+    metric3p = new SSDMetric3rdPartyComponent();
+    optimizer3p = new GDOptimizer3rdPartyComponent();
+
+    metric4p = new SSDMetric4thPartyComponent();
+    optimizer4p = new GDOptimizer4thPartyComponent();
+  }
+
+  virtual void TearDown() {
+    delete metric3p;
+    delete optimizer3p;
+    delete metric4p;
+    delete optimizer4p;
+  }
+  // types as if returned by our component factory
+  ComponentBase* metric3p;
+  ComponentBase* optimizer3p;
+  ComponentBase* metric4p;
+  ComponentBase* optimizer4p;
+
+};
+
+TEST_F( InterfaceTest, InterfaceNameTraits )
+{
+  EXPECT_STREQ(InterfaceName<MetricValueInterface>::Get(), "MetricValueInterface");
+  EXPECT_STREQ(InterfaceName<InterfaceAcceptor<MetricValueInterface> >::Get(), "MetricValueInterface");
+}
+
+TEST_F( InterfaceTest, DynamicCast )
+{
+  int returnval;
+  //metric3p should have a MetricValueInterface
+  MetricValueInterface* valueIF = dynamic_cast<MetricValueInterface*> (metric3p);
+  ASSERT_NE(valueIF, nullptr);
+  EXPECT_NO_THROW(returnval = valueIF->GetValue());
+
+  //metric3p should have a MetricDerivativeInterface
+  MetricDerivativeInterface* derivativeIF = dynamic_cast<MetricDerivativeInterface*> (metric3p);
+  ASSERT_NE(derivativeIF, nullptr);
+  EXPECT_NO_THROW(returnval = derivativeIF->GetDerivative());
+
+  //optimizer3p should have a OptimizerUpdateInterface
+  OptimizerUpdateInterface* updateIF = dynamic_cast<OptimizerUpdateInterface*> (optimizer3p);
+  ASSERT_NE(updateIF, nullptr);
+  //EXPECT_NO_THROW(returnval = updateIF->Update()); // Update can only be called if metric and optimizer are connected
+
+  //optimizer3p should have a InterfaceAcceptor<MetricValueInterface> 
+  InterfaceAcceptor<MetricValueInterface>* valueAcceptorIF = dynamic_cast<InterfaceAcceptor<MetricValueInterface>*> (optimizer3p);
+  ASSERT_NE(valueAcceptorIF, nullptr);
+
+  //optimizer3p should have a InterfaceAcceptor<MetricDerivativeInterface> 
+  InterfaceAcceptor<MetricDerivativeInterface>* derivativeAcceptorIF = dynamic_cast<InterfaceAcceptor<MetricDerivativeInterface>*> (optimizer3p);
+  ASSERT_NE(derivativeAcceptorIF, nullptr);
+  
+}
+
+TEST_F( InterfaceTest, ConnectByName )
+{
+  interfaceStatus IFstatus;
+  EXPECT_NO_THROW(IFstatus = optimizer3p->ConnectFrom("MetricValueInterface", metric3p));
+  EXPECT_EQ(IFstatus, interfaceStatus::success);
+
+  EXPECT_NO_THROW(IFstatus = optimizer3p->ConnectFrom("MetricValueInterface", metric4p));
+  EXPECT_EQ(IFstatus, interfaceStatus::success);
+
+  EXPECT_NO_THROW(IFstatus = optimizer4p->ConnectFrom("MetricValueInterface", metric3p));
+  EXPECT_EQ(IFstatus, interfaceStatus::success);
+
+  EXPECT_NO_THROW(IFstatus = optimizer4p->ConnectFrom("MetricValueInterface", metric4p));
+  EXPECT_EQ(IFstatus, interfaceStatus::success);
+
+
+  EXPECT_NO_THROW(IFstatus = optimizer3p->ConnectFrom("MetricDerivativeInterface", metric3p));
+  EXPECT_EQ(IFstatus, interfaceStatus::success);
+
+  EXPECT_NO_THROW(IFstatus = optimizer3p->ConnectFrom("MetricDerivativeInterface", metric4p));
+  EXPECT_EQ(IFstatus, interfaceStatus::noprovider);
+
+  EXPECT_NO_THROW(IFstatus = optimizer4p->ConnectFrom("MetricDerivativeInterface", metric3p));
+  EXPECT_EQ(IFstatus, interfaceStatus::noaccepter);
+
+}
+
+TEST_F(InterfaceTest, ConnectAll)
+{
+  int connectionCount = 0;
+  EXPECT_NO_THROW(connectionCount = optimizer3p->ConnectFrom(metric3p));
+  EXPECT_EQ(connectionCount, 2); // both MetricValueInterface and MetricDerivativeInterface are connected
+
+  EXPECT_NO_THROW(connectionCount = optimizer3p->ConnectFrom(metric4p));
+  EXPECT_EQ(connectionCount, 1); // only MetricValueInterface is connected
+
+  EXPECT_NO_THROW(connectionCount = optimizer4p->ConnectFrom(metric3p));
+  EXPECT_EQ(connectionCount, 1); // only MetricValueInterface is connected
+
+  EXPECT_NO_THROW(connectionCount = optimizer4p->ConnectFrom(metric4p));
+  EXPECT_EQ(connectionCount, 1); // only MetricValueInterface is connected
+
+
+  EXPECT_NO_THROW(connectionCount = metric4p->ConnectFrom(optimizer4p));
+  EXPECT_EQ(connectionCount, 0); // cannot connect in this direction
+}
+
+} // namespace elx