diff --git a/.gitignore b/.gitignore
index 30944692f3e9965ae406199abc5a3a2bca9196da..4befed30a1c63e1cd7071109bbaae5f687c583f4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
 .DS_Store
-build
+.idea
diff --git a/.travis.yml b/.travis.yml
index eddb5e133ef5f2d616acf59f612603ae4b2ecf79..8519f8302c78d7103fbe53cbe1a1d66a5a2fd4ff 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,11 @@
+sudo: false
+
 language: cpp
 
+os:
+  - linux
+  - osx
+
 compiler:
   - clang
   - gcc
@@ -21,4 +27,7 @@ before_script:
 script:
   - cmake ../SuperElastix/SuperBuild
   - make --jobs=2 | grep -v '^--' | grep -v '^Installing'
-  - make test
+
+after_sucess:
+  - cd Elastix-build
+  - ctest
diff --git a/CMake/elxCompilerFlags.cmake b/CMake/elxCompilerFlags.cmake
index 171a36b1bdafb1f2d1b939e3708e1203f8642dcf..8728ded6e8665a0d4b18741e224da9f64ceca865 100644
--- a/CMake/elxCompilerFlags.cmake
+++ b/CMake/elxCompilerFlags.cmake
@@ -9,4 +9,4 @@ set( CompilerFlags
   CMAKE_C_FLAGS_MINSIZEREL
   CMAKE_C_FLAGS_RELEASE
   CMAKE_C_FLAGS_RELWITHDEBINFO
-)
+)
\ No newline at end of file
diff --git a/CMake/elxRequiredITKModules.cmake b/CMake/elxITKRequiredModules.cmake
similarity index 100%
rename from CMake/elxRequiredITKModules.cmake
rename to CMake/elxITKRequiredModules.cmake
diff --git a/CMake/elxWinConfig.cmake b/CMake/elxWinConfig.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..c9a8eb734b8260f259e95fa5be4f6dd3605ea79d
--- /dev/null
+++ b/CMake/elxWinConfig.cmake
@@ -0,0 +1,19 @@
+# Visual Studio complains if paths are too long
+
+string( LENGTH "${CMAKE_CURRENT_SOURCE_DIR}" n )
+if( n GREATER 50 )
+message(
+  FATAL_ERROR
+  "ITK source code directory path length is too long (${n} > 50)."
+  "Please move the ITK source code directory to a directory with a shorter path."
+  )
+endif()
+
+string( LENGTH "${CMAKE_CURRENT_BINARY_DIR}" n )
+if( n GREATER 50 )
+message(
+  FATAL_ERROR
+  "ITK build directory path length is too long (${n} > 50)."
+  "Please set the ITK build directory to a directory with a shorter path."
+  )
+endif()
diff --git a/CMake/elxGoogleTestWinConfig.cmake b/CMake/elxWinConfigGoogleTest.cmake
similarity index 56%
rename from CMake/elxGoogleTestWinConfig.cmake
rename to CMake/elxWinConfigGoogleTest.cmake
index e72a8726f26a278eca4fcdee0471de494b67035d..75a5ac06f7db5c2020b3c4e11e85b572e07abf3f 100644
--- a/CMake/elxGoogleTestWinConfig.cmake
+++ b/CMake/elxWinConfigGoogleTest.cmake
@@ -1,6 +1,6 @@
-include( ${CMAKE_SOURCE_DIR}/CMake/elxCompilerFlags.cmake )
+# GoogleTest needs static linking
 
+include( elxCompilerFlags.cmake )
 foreach( CompilerFlag ${CompilerFlags} )
-  # GoogleTest needs static linking
   string( REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}" )
 endforeach()
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ec355d9a9510d0d968a5e95d38296e604f04b1ec..c5a3e96f42343649c90a9bd5889ca4b03d978616 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,14 +1,24 @@
 cmake_minimum_required( VERSION 2.8 )
 
+# Include SuperElastix CMake scripts
+list( APPEND CMAKE_MODULE_PATH 
+  "${CMAKE_CURRENT_SOURCE_DIR}/CMake"
+)
+
+if( CMAKE_HOST_WIN32 )
+  include( elxWinConfig.cmake )
+endif()
+
 #---------------------------------------------------------------------
-project( elastix )
+project( Elastix )
 
 #---------------------------------------------------------------------
 # ITK
 
 find_package( ITK REQUIRED )
+set( ITK_NO_IO_FACTORY_REGISTER_MANAGER 1 )
 include( ${ITK_USE_FILE} )
-include( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/elxRequiredITKModules.cmake" )
+include( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/elxITKRequiredModules.cmake" )
 
 #---------------------------------------------------------------------
 # Build Elastix
@@ -16,11 +26,14 @@ include( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/elxRequiredITKModules.cmake" )
 #---------------------------------------------------------------------
 # Testing
 
-# Do not build tests by default since this requires GoogleTest submodule
-# to be initialized. Otherwise users may see FATAL_ERRORs out of the box.
-# The SuperBuild will correctly initialize the GoogleTest submodule and 
-# build tests by default.
-option( ELASTIX_BUILD_TESTING "Enable building tests." OFF )
+# Build tests by default
+option( ELASTIX_BUILD_TESTING "Enable building tests." ON )
+
+# ExternalData module requires newer CMake versions
+if( CMAKE_VERSION VERSION_LESS 2.8.11 )
+  set( ELASTIX_BUILD_TESTING OFF FORCE )
+  message( STATUS "ELASTIX_BUILD_TESTING was set to OFF because CMake version is less than 2.8.11")
+endif()
 
 if( ELASTIX_BUILD_TESTING )
   enable_testing()
@@ -34,5 +47,5 @@ mark_as_advanced( ELASTIX_BUILD_DOXYGEN )
 option( ELASTIX_BUILD_DOXYGEN "Enable building Doxygen documentation." OFF )
 
 mark_as_advanced( ELASTIX_BUILD_READTHEDOCS )
-option( ELASTX_BUILD_READTHEDOCS "Enable building readthedocs.org documentation." OFF )
+option( ELASTIX_BUILD_READTHEDOCS "Enable building readthedocs.org documentation." OFF )
 
diff --git a/SuperBuild/CMakeLists.txt b/SuperBuild/CMakeLists.txt
index 12a9ed5a81673f264179d485fe593116bf538361..cff7bb5aec197b58bc119bf198014d2991bd6f36 100644
--- a/SuperBuild/CMakeLists.txt
+++ b/SuperBuild/CMakeLists.txt
@@ -1,7 +1,7 @@
 cmake_minimum_required( VERSION 2.8 )
 
 #---------------------------------------------------------------------
-project( elastixSuperBuild )
+project( ElastixSuperBuild )
 
 find_package( Git REQUIRED )
 
@@ -13,6 +13,8 @@ set( CMAKE_MODULE_PATH
   ${CMAKE_MODULE_PATH}
 )
 
+set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH "SuperBuild install directory" FORCE)
+
 #---------------------------------------------------------------------
 # Elastix SuperBuild configuration
 
@@ -29,12 +31,12 @@ option( ELASTIX_BUILD_EXAMPLES "Enable building examples." ON )
 option( ELASTIX_BUILD_TESTING "Enable building tests." ON )
 
 if( ELASTIX_BUILD_TESTING )
-  mark_as_advanced( ELASTIX_BUILD_CTESTS )
-  option( ELASTIX_BUILD_CTESTS "Enable CTests." OFF )
+  option( ELASTIX_BUILD_BENCHMARKING "Enable building benchmarks." ON )
+  option( ELASTIX_BUILD_DASHBOARD "Enable building benchmarks." ON )
 endif()
 
 #---------------------------------------------------------------------
-# Build ITK as external project
+# Build ITK
 
 set( ITK_VERSION_MAJOR "4" )
 set( ITK_VERSION_MINOR "7" )
@@ -53,7 +55,7 @@ else()
 endif()
 
 #---------------------------------------------------------------------
-# Build Elastix as an external project
+# Build Elastix
 
 include( Elastix )
 
diff --git a/SuperBuild/Elastix.cmake b/SuperBuild/Elastix.cmake
index 130f5595e11ee400642750827c814c3604e48761..d6bf55178d1d5674f14c9a5bd3f3fc7a93dcb3bd 100644
--- a/SuperBuild/Elastix.cmake
+++ b/SuperBuild/Elastix.cmake
@@ -4,11 +4,11 @@ ExternalProject_Add( ${proj}
   DOWNLOAD_COMMAND ""
   SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..
   BINARY_DIR ${proj}-build
-  INSTALL_DIR ${CMAKE_INSTALL_PREFIX}
   CMAKE_ARGS
     --no-warn-unused-cli
     -DELASTIX_BUILD_TESTING:BOOL=${ELASTIX_BUILD_TESTING}
-    -DELASTIX_BUILD_CTESTS:BOOL=${ELASTIX_BUILD_CTESTS}
+    -DELASTIX_BUILD_BENCHMARKING:BOOL=${ELASTIX_BUILD_BENCHMARKING}
+    -DELASTIX_BUILD_DASHBOARD:BOOL=${ELASTIX_BUILD_DASHBOARD}
     -DITK_DIR:PATH=${ITK_DIR}
   DEPENDS ${ELASTIX_DEPENDENCIES}
   INSTALL_COMMAND ""
diff --git a/Testing/Benchmark/BSplineRegistration.cxx b/Testing/Benchmark/BSplineRegistration.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8a8a73b44e539e6ffb30806b08346f47a92256dd
--- /dev/null
+++ b/Testing/Benchmark/BSplineRegistration.cxx
@@ -0,0 +1,137 @@
+/**
+ * Benchmarking multi-resolution non-rigid b-spline registration 
+ * with mutual information in ITK, Elastix and ANTs
+ */
+
+#include "itkImage.h"
+#include "itkImageFileReader.h"
+#include "itkImageFileWriter.h"
+
+// DeformableRegistration1
+#include "itkRescaleIntensityImageFilter.h"
+#include "itkHistogramMatchingImageFilter.h"
+#include "itkFEMRegistrationFilter.h"
+
+#include "gtest/gtest.h"
+
+class itkExamples : public ::testing::Test
+{
+protected:
+
+    virtual void SetUp()
+    {
+        const char *fixedImageName, *movingImageName;
+        if ( argc < 2 )
+        {
+          std::cout << "Image filenames missing." << std::endl;
+          std::cout << "Usage: " << argv[0] << " fixedImageFilename movingImageFilename"
+                    << std::endl;
+          return EXIT_FAILURE;
+        }
+        else
+        {
+          fixedImageFilename = argv[1];
+          movingImageFilename = argv[2];
+        }
+    }
+
+};
+
+TEST_F( BSplineRegistration, ITK ) {
+
+  const unsigned int ImageDimension = 2;
+  typedef unsigned char PixelType;
+  typedef itk::Image< PixelType, ImageDimension > ImageType;
+
+  const unsigned int SplineOrder = 3;
+  typedef double CoordinateRepType;
+  
+  // Transform
+  typedef itk::BSplineDeformableTransform< CoordinateRepType,
+                                           SpaceDimension,
+                                           SplineOrder > TransformType;
+
+  typedef TransformType::RegionType RegionType;
+  RegionType bsplineRegion;
+  RegionType::SizeType  gridSizeOnImage;
+  RegionType::SizeType  gridBorderSize;
+  RegionType::SizeType  totalGridSize;
+ 
+  gridSizeOnImage.Fill( 5 );
+  gridBorderSize.Fill( 3 ); // Border for spline order = 3 ( 1 lower, 2 upper )
+  totalGridSize = gridSizeOnImage + gridBorderSize;
+ 
+  bsplineRegion.SetSize( totalGridSize );
+ 
+  typedef TransformType::SpacingType SpacingType;
+  SpacingType spacing = fixedImage->GetSpacing();
+ 
+  typedef TransformType::OriginType OriginType;
+  OriginType origin = fixedImage->GetOrigin();
+ 
+  ImageType::SizeType fixedImageSize = fixedRegion.GetSize();
+ 
+  for(unsigned int r=0; r<ImageDimension; r++)
+  {
+    spacing[r] *= static_cast<double>(fixedImageSize[r] - 1)  /
+                  static_cast<double>(gridSizeOnImage[r] - 1);
+  }
+ 
+  ImageType::DirectionType gridDirection = fixedImage->GetDirection();
+  SpacingType gridOriginOffset = gridDirection * spacing;
+ 
+  OriginType gridOrigin = origin - gridOriginOffset;
+ 
+  transform->SetGridSpacing( spacing );
+  transform->SetGridOrigin( gridOrigin );
+  transform->SetGridRegion( bsplineRegion );
+  transform->SetGridDirection( gridDirection );
+
+  typedef TransformType::ParametersType ParametersType;
+  const unsigned int numberOfParameters = transform->GetNumberOfParameters();
+  ParametersType parameters( numberOfParameters );
+  parameters.Fill( 0.0 );
+  transform->SetParameters( parameters );
+
+  // Optimizer
+  typedef itk::LBFGSOptimizer OptimizerType;
+
+  optimizer->SetGradientConvergenceTolerance( 0.05 );
+  optimizer->SetLineSearchAccuracy( 0.9 );
+  optimizer->SetDefaultStepLength( .5 );
+  optimizer->TraceOn();
+  optimizer->SetMaximumNumberOfFunctionEvaluations( 1024 );
+ 
+  // Metric
+  typedef itk::MeanSquaresImageToImageMetric< ImageType,
+                                              ImageType > MetricType;
+
+  // Interpolator
+  typedef itk:: LinearInterpolateImageFunction< ImageType,
+                                                double >  InterpolatorType;
+
+  // Setup the registration
+  typedef itk::ImageRegistrationMethod< ImageType,
+                                        ImageType > RegistrationType;
+
+  RegistrationType::Pointer registration  = RegistrationType::New();
+  registration->SetNumberOfThreads( 1 );
+  registration->SetMetric( MetricType::New() );
+  registration->SetOptimizer( OptimizerType::New() );
+  registration->SetInterpolator( InterpolatorType::New() );
+ 
+  TransformType::Pointer transform = TransformType::New();
+  registration->SetTransform( transform );
+
+  registration->SetFixedImage( fixedImage  );
+  registration->SetMovingImage(  movingImage );
+ 
+  ImageType::RegionType fixedRegion = fixedImage->GetBufferedRegion();
+  registration->SetFixedImageRegion( fixedRegion );
+ 
+  registration->SetInitialTransformParameters( transform->GetParameters() );
+
+  // Execute
+  EXPECT_NO_THROW( registration->Update() );
+
+}
\ No newline at end of file
diff --git a/Testing/Benchmark/CMakeLists.txt b/Testing/Benchmark/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3004ccdf3e61caabdafab9c49e78855cd53ab8e7
--- /dev/null
+++ b/Testing/Benchmark/CMakeLists.txt
@@ -0,0 +1,37 @@
+#
+set( GTEST_OPTIONS
+  -gtest_output
+)
+
+#---------------------------------------------------------------------
+# To add a benchmark to the build system, append it to the list below. 
+# Any GoogleTests in these files are automatically added to CTest.
+
+set( ElastixBenchmarkSource
+  elxExampleBenchmark.cxx
+)
+
+#---------------------------------------------------------------------
+# To add data to a benchmark, create a list "${filename}Data" (without
+# the filename extension) and add data to this list.
+
+set( elxExampleBenchmarkData
+  DATA{Testing/Data/Input/BrainProtonDensitySlice.png}
+  DATA{Testing/Data/Input/BrainProtonDensitySliceR10X13Y17.png}
+)
+
+#---------------------------------------------------------------------
+# Build executables
+
+foreach( ElastixBenchmarkFilename ${ElastixBenchmarkSource} )
+  string( REPLACE ".cxx" "" ElastixBenchmark ${ElastixBenchmarkFilename} )
+  add_executable( ${ElastixBenchmark} ${ElastixBenchmarkFilename} )
+  target_link_libraries( ${ElastixBenchmark} ${ELASTIX_LIBRARIES} ${ITK_LIBRARIES} ${TEST_LIBRARIES} )
+
+  ExternalData_Add_Test( "${ElastixBenchmark}ExternalDataTarget"
+    NAME ${ElastixBenchmark}
+    COMMAND "${ElastixBenchmark} ${${ElastixBenchmarkTest}Data} ${GTEST_OPTIONS}"
+  )
+
+  ExternalData_Add_Target( "${ElastixBenchmark}ExternalDataTarget"} )
+endforeach()
diff --git a/Testing/CMakeLists.txt b/Testing/CMakeLists.txt
index 7343cdc14ac9e8409922e978b081018ef3f539b8..ea6d3697c6ed80937d7202666712bfc5954c3ad1 100644
--- a/Testing/CMakeLists.txt
+++ b/Testing/CMakeLists.txt
@@ -1,13 +1,55 @@
-#---------------------------------------------------------------------
+# ---------------------------------------------------------------------
+# Download test data
+
+# ExternalData module requires CMake version 2.8.11
+if( CMAKE_VERSION VERSION_LESS 2.8.11 )
+  message( FATAL_ERROR "Building tests require CMake 2.8.11 or newer." )
+endif()
+
+include( ExternalData )
+
+list( APPEND ExternalData_URL_TEMPLATES
+  "http://midas3.kitware.com/midas/api/rest?method=midas.bitstream.download&checksum=%(hash)&algorithm=%(algo)"
+  "https://midas3.kitware.com/midas/api/rest?method=midas.bitstream.download&checksum=%(hash)&algorithm=%(algo)"
+)
+
+# Scan the Data directory for content links on the form "[filename].[ext].md5". 
+# The content links contains md5 hashes that are checked for consistensy  
+# against files downloaded from servers in ExternalData_URL_TEMPLATES. These 
+# files are placed in a corresponding location in the build directory.
+file( GLOB_RECURSE ElastixDataContentLinks "*.md5" )
+foreach(ElastixDataContentLink ${ElastixDataContentLinks})
+  string( REGEX REPLACE "\\.md5$" "" ElastixDataContentLink ${ElastixDataContentLink} )
+  ExternalData_Expand_Arguments( ElastixData
+    ElastixDataFilenames
+    DATA{${ElastixDataContentLink}}
+  )
+endforeach()
+
+# Test data is downloaded when this target is built
+ExternalData_Add_Target( ElastixData )
+
+# ---------------------------------------------------------------------
 # Setup GoogleTest
 
-if( NOT EXISTS "${CMAKE_SOURCE_DIR}/Testing/GoogleTest/.git" )
-  message( FATAL_ERROR "Could not find GoogleTest submodule. Please run 
-git submodule update --init in the source directory to compile tests." )
+find_package( Git )
+if( NOT EXISTS "${CMAKE_SOURCE_DIR}/Testing/GoogleTest/.git" AND GIT_EXECUTABLE )
+  execute_process( 
+  	COMMAND ${GIT_EXECUTABLE} submodule update --init
+    WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
+    OUTPUT_QUIET
+  )
+endif()
+
+if( NOT EXISTS ${CMAKE_SOURCE_DIR}/Testing/GoogleTest/.git )
+  message( 
+  	FATAL_ERROR "Could not find GoogleTest submodule. Please run 
+  	git submodule update --init in the source directory to compile tests."
+  )
 endif()
 
 if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC" )
-  include( ${CMAKE_SOURCE_DIR}/CMake/elxGoogleTestWinConfig.cmake )
+  include( elxWinConfigGoogleTest.cmake )
 endif()
 
 add_subdirectory( GoogleTest )
@@ -20,48 +62,24 @@ set( TEST_LIBRARIES
   gtest_main
 )
 
-#---------------------------------------------------------------------
-# To add a test to the build system, append it to the list below. 
-# Any GoogleTests in these files are automatically added to CTest.
+# ---------------------------------------------------------------------
+# Build test suite
 
-set( ElastixUnitTestSource
-  elxExampleTest.cxx
-)
-
-#---------------------------------------------------------------------
-# Setup ExternalData
-
-# ExternalData module was introduced in CMake version 2.8.11
-cmake_minimum_required( VERSION 2.8.11 )
-
-include( ExternalData )
-
-list( APPEND ExternalData_URL_TEMPLATES
-  "http://midas3.kitware.com/midas/api/rest?method=midas.bitstream.download&checksum=%(hash)&algorithm=%(algo)"
-  "https://midas3.kitware.com/midas/api/rest?method=midas.bitstream.download&checksum=%(hash)&algorithm=%(algo)"
-)
-
-#---------------------------------------------------------------------
-# To add data to a tests, create a list "${filename}Data" (without
-# the filename extension) and add data to this list.
-
-set( elxExampleTestData
-  DATA{Data/Input/BrainProtonDensitySliceR10X13Y17.png}
-)
-
-#---------------------------------------------------------------------
-# Build test executables
+# Unit tests
+add_subdirectory( Unit )
 
-foreach( ElastixUnitTestFilename ${ElastixUnitTestSource} )
-  string( REPLACE ".cxx" "" ElastixUnitTest ${ElastixUnitTestFilename} )
-  add_executable( ${ElastixUnitTest} ${ElastixUnitTestFilename} )
-  target_link_libraries( ${ElastixUnitTest} ${ELASTIX_LIBRARIES} ${ITK_LIBRARIES} ${TEST_LIBRARIES} )
+# Benchmarks
+option( ELASTIX_BUILD_BENCHMARKING "Enable building benchmarks." OFF )
 
-  ExternalData_Add_Test( "${ElastixUnitTest}ExternalDataTarget"
-    NAME ${ElastixUnitTest}
-    COMMAND ${ElastixUnitTest} ${${ElastixUnitTest}Data}
-  )
+if( ${ELASTIX_BUILD_BENCHMARKING} )
+	add_subdirectory( Benchmark )
+endif()
 
-  ExternalData_Add_Target( "${ElastixUnitTest}ExternalDataTarget"} )
-endforeach()
+# ---------------------------------------------------------------------
+# Configure dashboard
+mark_as_advanced( ELASTIX_BUILD_DASHBOARD )
+option( ELASTIX_BUILD_DASHBOARD "Enable elastix dashboard." OFF )
 
+if( ${ELASTIX_BUILD_DASHBOARD} )
+  add_subdirectory( Dashboard )
+endif()
diff --git a/Testing/Dashboard/CMakeLists.txt b/Testing/Dashboard/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..85e1fb47a084569b852c7ccdae81b32b6efd4347
--- /dev/null
+++ b/Testing/Dashboard/CMakeLists.txt
@@ -0,0 +1,53 @@
+# ---------------------------------------------------------------------
+# Settings
+mark_as_advanced( ELASTIX_DASHBOARD_HOST )
+set( ELASTIX_DASHBOARD_HOST "elastix" )
+
+mark_as_advanced( ELASTIX_DASHBOARD_ELASTICSEARCH_PORT )
+set( ELASTIX_DASHBOARD_ELASTICSEARCH_PORT 9200 )
+
+mark_as_advanced( ELASTIX_DASHBOARD_LOGSTASH_PORT )
+set( ELASTIX_DASHBOARD_LOGSTASH_PORT 5043 )
+
+mark_as_advanced( ELASTIX_DASHBOARD_KIBANA_PORT )
+set( ELASTIX_DASHBOARD_KIBANA_PORT 5601 )
+
+mark_as_advanced( ELASTIX_DASHBOARD_SOURCE_DIR )
+set( ELASTIX_DASHBOARD_SOURCE_DIR "${CMAKE_SOURCE_DIR}/Testing/Dashboard" )
+
+mark_as_advanced( ELASTIX_DASHBOARD_BINARY_DIR )
+set( ELASTIX_DASHBOARD_BINARY_DIR "${CMAKE_BINARY_DIR}/Testing/Dashboard" )
+
+mark_as_advanced( ELASTIX_DASHBOARD_LOGSTASH_CERTIFICATE )
+set( ELASTIX_DASHBOARD_LOGSTASH_CERTIFICATE "elxLogstashForwarder.crt" )
+
+mark_as_advanced( ELASTIX_DASHBOARD_LOGSTASH_RSA_PRIVATE_KEY )
+set( ELASTIX_DASHBOARD_LOGSTASH_RSA_PRIVATE_KEY "elxLogstashForwarder.key" )
+
+mark_as_advanced( ELASTIX_DASHBOARD_VOLUME )
+set( ELASTIX_DASHBOARD_VOLUME "${ELASTIX_DASHBOARD_BINARY_DIR}/Data" )
+
+if( NOT EXISTS "${ELASTIX_DASHBOARD_VOLUME}" )
+  message( STATUS
+    "ELASTIX_DASHBOARD_VOLUME points to the default ${CMAKE_BINARY_DIR}/Testing/Dashboard/Data path in your build directory. Point to another directory on your local machine to ensure dashboard state is saved between builds."
+  )
+
+  file( MAKE_DIRECTORY "${ELASTIX_DASHBOARD_VOLUME}" )
+endif()
+
+# ---------------------------------------------------------------------
+# Configure 
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/docker-compose.yml.in
+  ${ELASTIX_DASHBOARD_BINARY_DIR}/docker-compose.yml
+)
+
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/elxLogstash.conf.in
+  ${ELASTIX_DASHBOARD_BINARY_DIR}/elxLogstash/elxLogstash.conf
+)
+
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/elxLogstashForwarder.conf.in
+  ${ELASTIX_DASHBOARD_BINARY_DIR}/elxLogstashForwarder.conf
+)
\ No newline at end of file
diff --git a/Testing/Dashboard/docker-compose.yml.in b/Testing/Dashboard/docker-compose.yml.in
new file mode 100644
index 0000000000000000000000000000000000000000..6faad275504d0b5fb4cdcf708d106f40254be8d9
--- /dev/null
+++ b/Testing/Dashboard/docker-compose.yml.in
@@ -0,0 +1,17 @@
+elastix:
+    image: willdurand/elk
+    ports:
+        - "80:80"
+        - "@ELASTIX_DASHBOARD_LOGSTASH_PORT@:@ELASTIX_DASHBOARD_LOGSTASH_PORT@"
+    volumes_from:
+        - data
+
+data:
+    image: busybox
+    volumes:
+        - @ELASTIX_DASHBOARD_SOURCE_DIR@:/etc/ssl
+        - @ELASTIX_DASHBOARD_VOLUME@:/data                   
+        - @ELASTIX_DASHBOARD_BINARY_DIR@/elxLogstash:/etc/logstash 
+
+              
+                     
\ No newline at end of file
diff --git a/Testing/Dashboard/elxLogstash.conf.in b/Testing/Dashboard/elxLogstash.conf.in
new file mode 100644
index 0000000000000000000000000000000000000000..454a843007c028b8d2d62c1eb5a08264289ab53e
--- /dev/null
+++ b/Testing/Dashboard/elxLogstash.conf.in
@@ -0,0 +1,20 @@
+input {
+  lumberjack {
+    port => @ELASTIX_DASHBOARD_LOGSTASH_PORT@
+    ssl_certificate => "/etc/ssl/@ELASTIX_DASHBOARD_LOGSTASH_CERTIFICATE@"
+    ssl_key => "/etc/ssl/@ELASTIX_DASHBOARD_LOGSTASH_RSA_PRIVATE_KEY@"
+  }
+}
+
+filter {
+  xml {
+    source => message
+    target => result
+  }
+}
+
+output {
+  elasticsearch {
+  	protocol => http
+  }
+}
\ No newline at end of file
diff --git a/Testing/Dashboard/elxLogstashForwarder.conf.in b/Testing/Dashboard/elxLogstashForwarder.conf.in
new file mode 100644
index 0000000000000000000000000000000000000000..923c158e35a2f8666a5316bc81446d4bd429365b
--- /dev/null
+++ b/Testing/Dashboard/elxLogstashForwarder.conf.in
@@ -0,0 +1,20 @@
+{
+  "network": {
+    "servers": [ "@ELASTIX_DASHBOARD_HOST@:@ELASTIX_DASHBOARD_LOGSTASH_PORT@" ],
+    "timeout": 15,
+    "ssl certificate": "@ELASTIX_DASHBOARD_SOURCE_DIR@/@ELASTIX_DASHBOARD_LOGSTASH_CERTIFICATE@",
+    "ssl key": "@ELASTIX_DASHBOARD_SOURCE_DIR@/@ELASTIX_DASHBOARD_LOGSTASH_RSA_PRIVATE_KEY@",
+    "ssl ca": "@ELASTIX_DASHBOARD_SOURCE_DIR@/@ELASTIX_DASHBOARD_LOGSTASH_CERTIFICATE@"
+  },
+  "files": [
+    {
+      "paths": [
+        "@CMAKE_BINARY_DIR@/Testing/Unit/*.xml"
+       ],
+      "fields": { 
+        "type": "unittest",
+        "lib": "elastix" 
+      }
+    }
+   ]
+}
diff --git a/Testing/Dashboard/elxLogstashForwarder.crt b/Testing/Dashboard/elxLogstashForwarder.crt
new file mode 100644
index 0000000000000000000000000000000000000000..56ef6e0dcf697be1be407db7ca75cf31112821d0
--- /dev/null
+++ b/Testing/Dashboard/elxLogstashForwarder.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDGjCCAgKgAwIBAgIJAMF8GSVtnyB6MA0GCSqGSIb3DQEBBQUAMBIxEDAOBgNV
+BAMTB2VsYXN0aXgwHhcNMTUwODEyMTQxNjE1WhcNMTUwOTExMTQxNjE1WjASMRAw
+DgYDVQQDEwdlbGFzdGl4MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
+01P404f+W/aBLxlQTFyHy1o7m07edUmFIjJuN9JjGTzZtlhAEc7dXJ8fUwr/hnLq
+HUeaGRbNcpFDj+/Xq2W9jH7/VyxivA8Ib7ycLNxywgmheZVxXetPIeYmK+Rqovyd
+GhMcU0WMv/3OslFjf92PLegFgRYbmJa7rEH+I0MD1hE1rn1AIJeU4nVCUrtQON6g
+icDEZSNwVSuLfdiuHCMcAVWx+pQIyHji6EoyIBjNsF8LoBZoMY5N+qRph8tt9k1N
+GemQoaZWd926jWgrsSSrAfgtMxw43TXwCFe8RiL8L+pZlN4xxYjQj1/PtTowqjzL
+dYqWAT0o5zwlqkrNgjTuYwIDAQABo3MwcTAdBgNVHQ4EFgQU8onFqrecR/J81ZFi
+gonexjVf8yAwQgYDVR0jBDswOYAU8onFqrecR/J81ZFigonexjVf8yChFqQUMBIx
+EDAOBgNVBAMTB2VsYXN0aXiCCQDBfBklbZ8gejAMBgNVHRMEBTADAQH/MA0GCSqG
+SIb3DQEBBQUAA4IBAQCYalhVZpN/F/Cux/KRBuOyyVxD+tOM7PDlXuuGMcxZ8PTH
+sYK3MLBUvGnn90R6YIF+pmZC40hkau12xGRnlyNLa0EpnAd77SGlaB/y9Ix6RCDd
+PRvdEZodknXzS5sDw+A9pA0JtZANrAXHrELPXjfp5vdf4EUH/o7TTh3XzTEIokwp
+VY6557E17BYsTHHebWPSiDzCeS9y6PtdiZczuHrd7+K+vWgVcgmQ0fdudWwcMOEC
+8s6O8uQGrc1v9nSyT93C9MPCWnuZ2McFX4JPSwaqAaKCTcnc8GAcqk4O5ruQ/8u/
+xSNQsoYpFi2BawOdPDqyMKn4khkREWTq0+T+7Kq2
+-----END CERTIFICATE-----
diff --git a/Testing/Dashboard/elxLogstashForwarder.key b/Testing/Dashboard/elxLogstashForwarder.key
new file mode 100644
index 0000000000000000000000000000000000000000..9537cddd201e50e6d661444da8e85c5294b617c3
--- /dev/null
+++ b/Testing/Dashboard/elxLogstashForwarder.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEA01P404f+W/aBLxlQTFyHy1o7m07edUmFIjJuN9JjGTzZtlhA
+Ec7dXJ8fUwr/hnLqHUeaGRbNcpFDj+/Xq2W9jH7/VyxivA8Ib7ycLNxywgmheZVx
+XetPIeYmK+RqovydGhMcU0WMv/3OslFjf92PLegFgRYbmJa7rEH+I0MD1hE1rn1A
+IJeU4nVCUrtQON6gicDEZSNwVSuLfdiuHCMcAVWx+pQIyHji6EoyIBjNsF8LoBZo
+MY5N+qRph8tt9k1NGemQoaZWd926jWgrsSSrAfgtMxw43TXwCFe8RiL8L+pZlN4x
+xYjQj1/PtTowqjzLdYqWAT0o5zwlqkrNgjTuYwIDAQABAoIBAB6ug2LazMA3Utwu
+tazQhlqs2BidY8jtiqnDXqM2JXMllYpW175+JT9sTtT0tNKlXn4vxhy8Zcmrc36z
+WMGmvNVoHtReOluJZzUp0hblTrgDQ/FuFA6Jumx2iLY4rI7LVFfTzHn+kAfT5q2X
+CXYoCcClfh8WwZzuzYKd9jLSaP0sMKBqz7IAJDE3Ie3vzsznp56ZceMZqgqDjbgw
+p1Gt2eNNWdi0GXSxvv5x9o5UYCNCkmb9Ot3/l4aVMe+jxwtd6b0xjjIry/Orw4Y3
+L4Zu5x07np5K+RxKer9Y6zlKR6iyVME3r6a014dCoKVLpdUph+sTQq3qn2PmdFYk
+XM6eAlECgYEA///UzS31YTqsMehPWEHWF+TkqZJfVCegZgSCGOUXkPXAZoLzVwsK
+WwMILYMDR9ur9lJ7xzcBtSc9PylZFX0hFfHeCE30XHZ0CaX2f07cVI4WxRYCDtNJ
+7rAb7r1ADG4jWEEqMuGBliDT8Sp/2zZfD9q47JnTQsrhgSW1YwJHh1kCgYEA01Qc
+fJyYnlLdZnuKUwu2AJslOBup2Ntp8IFRpUSuaPrC3h/WqUU+ALhhtkI6ZZTqdmoo
+9aRqEFwIlLOU2J4PempwOh8tVQoAz37Ye+J5DDfqqn2KUeC28qHhmjHPBz7bw3wa
+Nfs73/KsDNIElnygmk6emlUcN1l1kW0hdRLp6BsCgYBiCI1seWITds2EWysvaB7d
+jZkHWvdImdgx2R4c/HYW3BVu7EzVk3PGwJV8IES8WuIydQnTkzwDLGCm9GWZ9g4a
+gkH9uiSO2Am9vCF2RTPY6YTMuo3VMZKJZkV8GlsRp4e/f0zyqSrf2/htzVGjF+I1
+hxPz/0BIvrq2o0MgBDpyGQKBgAeNS+9QEUwnHe5Zn9nT408mPDBDHNC5FpIXrPlA
++RKbU3don90wskSIUkWXHEshBTfyF0Cf/YJUJ6JYwIr1Kwxu3U/WaWJOlzTTDZ1v
+vG+pV+N71QOUCjWlf1BpU0KpBmV3+9/N+JfKLkfPAYb3MS4SfSx6uiVoNwFZawaq
+BF3dAoGAYFombeE1Ky5CqoCu31CUvAX8FXI+32fZYC2YBguc9FMIVU9NCeBLBDIB
+D24UchcTfJLtn1GIMjv8+OSwiv7g2LlHlMB0q6j0k+9xkA9sMn5BgbsNs6Nsa+hu
+pp9Kl4jib8r434jOp4RoxkA6toI6rw88M8GZHNee1PW3MwMcdm4=
+-----END RSA PRIVATE KEY-----
diff --git a/Testing/Unit/CMakeLists.txt b/Testing/Unit/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0e92b5a3dcfdaae64617d9dd983efeb558214089
--- /dev/null
+++ b/Testing/Unit/CMakeLists.txt
@@ -0,0 +1,32 @@
+#---------------------------------------------------------------------
+# To add a test to the build system, append it to the list below. 
+# Any GoogleTests in these files are automatically added to CTest and
+# the Kibana dashboard.
+
+set( ElastixUnitTestFilenames
+  elxExampleUnitTest.cxx
+)
+
+#---------------------------------------------------------------------
+# Set data directories
+set( ELASTIX_UNITTEST_INPUT_DATA_DIR ${CMAKE_CURRENT_BINARY_DIR}/Data/Input )
+set( ELASTIX_UNITTEST_BASELINE_DATA_DIR ${CMAKE_CURRENT_BINARY_DIR}/Data/Baseline )
+
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/elxTestHarness.h.in
+  ${CMAKE_CURRENT_BINARY_DIR}/elxTestHarness.h
+  ESCAPE_QUOTES
+)
+
+# Build tests
+foreach( ElastixUnitTestFilename ${ElastixUnitTestFilenames} )
+  # Build tests executables
+  string( REPLACE ".cxx" "" ElastixUnitTest ${ElastixUnitTestFilename} )
+  add_executable( "${ElastixUnitTest}" ${ElastixUnitTestFilename} )
+  target_link_libraries( "${ElastixUnitTest}" ${ELASTIX_LIBRARIES} ${ITK_LIBRARIES} ${TEST_LIBRARIES} )
+
+  ExternalData_Add_Test( ElastixData
+    NAME ${ElastixUnitTest}
+    COMMAND ${ElastixUnitTest} "--gtest_output=xml:${CMAKE_BINARY_DIR}/Testing/Unit/${ElastixUnitTest}.xml"
+  )
+endforeach()
diff --git a/Testing/Unit/Data/Input/BrainProtonDensitySlice.png.md5 b/Testing/Unit/Data/Input/BrainProtonDensitySlice.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..317f8a125578f6b03363ddc5c3ff4ce81209960e
--- /dev/null
+++ b/Testing/Unit/Data/Input/BrainProtonDensitySlice.png.md5
@@ -0,0 +1 @@
+073df8eb397d1746d2343c78dd4bd964
\ No newline at end of file
diff --git a/Testing/Data/Input/BrainProtonDensitySliceR10X13Y17.png.md5 b/Testing/Unit/Data/Input/BrainProtonDensitySliceR10X13Y17.png.md5
similarity index 100%
rename from Testing/Data/Input/BrainProtonDensitySliceR10X13Y17.png.md5
rename to Testing/Unit/Data/Input/BrainProtonDensitySliceR10X13Y17.png.md5
diff --git a/Testing/Unit/elxExampleUnitTest.cxx b/Testing/Unit/elxExampleUnitTest.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..725fa981e0ae8768ee500485f613190eb9edecea
--- /dev/null
+++ b/Testing/Unit/elxExampleUnitTest.cxx
@@ -0,0 +1,40 @@
+#include <stdlib.h>
+#include <time.h>
+
+#include "gtest/gtest.h"
+
+/**
+ * This example demonstrates the elastix framework.
+ * We run a couple of tests that outputs numbers for
+ * use on the dashboard.
+ */
+
+TEST( GoogleTest, Example0 )
+{
+  srand( time( NULL ) );
+  ASSERT_TRUE( true );
+}
+
+TEST( GoogleTest, Example1 )
+{
+    // Record random number between 0 and 9
+    int MetricValue = rand() % 10;
+    RecordProperty("MetricValue", MetricValue);
+    ASSERT_TRUE( true );
+}
+
+TEST( GoogleTest, Example2 )
+{
+    // Record random number between 10 and 19
+    int MetricValue = rand() % 10 + 10;
+    RecordProperty("MetricValue", MetricValue);
+    ASSERT_TRUE( true );
+}
+
+TEST( GoogleTest, Example3 )
+{
+    // Record random number between 20 and 29
+    int MetricValue = rand() % 10 + 20;
+    RecordProperty("MetricValue", MetricValue);
+    ASSERT_TRUE( true );
+}
\ No newline at end of file
diff --git a/Testing/Unit/elxTestHarness.h.in b/Testing/Unit/elxTestHarness.h.in
new file mode 100644
index 0000000000000000000000000000000000000000..8bdb97a716b0e259a1016dabd86123a5311d3244
--- /dev/null
+++ b/Testing/Unit/elxTestHarness.h.in
@@ -0,0 +1,7 @@
+#ifndef __ElastixTestHarness_h
+#define __ElastixTestHarness_h
+
+#define ELASTIX_UNITTEST_INPUT_DATA_DIR "@ELASTIX_UNITTEST_INPUT_DATA_DIR@"
+#define ELASTIX_INITTEST_BASELINE_DATA_DIR "@ELASTIX_UNITTEST_BASELINE_DATA_DIR@"
+
+#endif // __ElastixTestHarness_h
\ No newline at end of file
diff --git a/Testing/elxExampleTest.cxx b/Testing/elxExampleTest.cxx
deleted file mode 100644
index 1b3cfafc3e4748e901286b667bf0f3b3d3162ba4..0000000000000000000000000000000000000000
--- a/Testing/elxExampleTest.cxx
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "itkImage.h"
-#include "itkImageFileReader.h"
-#include "itkImageFileWriter.h"
-
-#include "gtest/gtest.h"
-
-TEST( GoogleTest, GoogleTest ) {
-  /**
-   * This example demonstrates the GoogleTest framework.
-   *
-   * When the test is built, the ExternalData CMake module 
-   * scans the Testing/Data directory for content links on  
-   * the form "[filename].[ext].md5" (text files with hashes).
-   * The content links are replaced with files from the file
-   * repository and checked for hash consistensy.
-   */
-
-  ASSERT_TRUE( true );
-}
\ No newline at end of file