diff --git a/Testing/Code/FeatureExtraction/otbImageFunctionAdaptor.cxx b/Testing/Code/FeatureExtraction/otbImageFunctionAdaptor.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d5d3d6e55144f4859ed44f35eeb7d8f6074c062f
--- /dev/null
+++ b/Testing/Code/FeatureExtraction/otbImageFunctionAdaptor.cxx
@@ -0,0 +1,306 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+#if defined(_MSC_VER)
+#pragma warning ( disable : 4786 )
+#endif
+
+#include "otbImage.h"
+#include "otbImageFileReader.h"
+#include "otbStreamingMinMaxImageFilter.h"
+
+#include "otbImageFunctionAdaptor.h"
+
+#include "otbFourierMellinDescriptorsImageFunction.h"
+#include "otbRealMomentsImageFunction.h"
+#include "otbComplexMomentsImageFunction.h"
+#include "otbFlusserMomentsImageFunction.h"
+#include "otbHuMomentsImageFunction.h"
+#include "otbRadiometricMomentsImageFunction.h"
+#include "otbLocalHistogramImageFunction.h"
+
+
+int otbImageFunctionAdaptorNew(int argc, char * argv[])
+{
+  typedef double InputPixelType;
+  const unsigned int Dimension = 2;
+
+  typedef otb::Image<InputPixelType,  Dimension>                        InputImageType;
+  
+  typedef otb::FourierMellinDescriptorsImageFunction<InputImageType>    FMDFunctionType;
+  typedef otb::RealMomentsImageFunction<InputImageType>                 RMFunctionType;
+  typedef otb::ComplexMomentsImageFunction<InputImageType>              CMFunctionType;
+  typedef otb::FlusserMomentsImageFunction<InputImageType>              FMFunctionType;
+  typedef otb::HuMomentsImageFunction<InputImageType>                   HMFunctionType;
+  typedef otb::RadiometricMomentsImageFunction<InputImageType>          RaMFunctionType;
+  typedef otb::LocalHistogramImageFunction<InputImageType>              LHFunctionType;
+
+  typedef otb::ImageFunctionAdaptor<FMDFunctionType>                    FMDImageFunctionAdaptorType;
+  typedef otb::ImageFunctionAdaptor<RMFunctionType>                     RMImageFunctionAdaptorType;
+  typedef otb::ImageFunctionAdaptor<CMFunctionType>                     CMImageFunctionAdaptorType;
+  typedef otb::ImageFunctionAdaptor<FMFunctionType>                     FMImageFunctionAdaptorType;
+  typedef otb::ImageFunctionAdaptor<HMFunctionType>                     HMImageFunctionAdaptorType;
+  typedef otb::ImageFunctionAdaptor<RaMFunctionType>                    RaMImageFunctionAdaptorType;
+  typedef otb::ImageFunctionAdaptor<LHFunctionType>                     LHImageFunctionAdaptorType;
+
+  // Instantiating objects
+  FMDImageFunctionAdaptorType::Pointer FMDadaptedFunction = FMDImageFunctionAdaptorType::New();
+  std::cout << FMDadaptedFunction << std::endl;
+  RMImageFunctionAdaptorType::Pointer RMadaptedFunction = RMImageFunctionAdaptorType::New();
+  std::cout << RMadaptedFunction << std::endl;
+  CMImageFunctionAdaptorType::Pointer CMadaptedFunction = CMImageFunctionAdaptorType::New();
+  std::cout << CMadaptedFunction << std::endl;
+  FMImageFunctionAdaptorType::Pointer FMadaptedFunction = FMImageFunctionAdaptorType::New();
+  std::cout << FMadaptedFunction << std::endl;
+  HMImageFunctionAdaptorType::Pointer HMadaptedFunction = HMImageFunctionAdaptorType::New();
+  std::cout << HMadaptedFunction << std::endl;
+  RaMImageFunctionAdaptorType::Pointer RaMadaptedFunction = RaMImageFunctionAdaptorType::New();
+  std::cout << RaMadaptedFunction << std::endl;
+  //LHImageFunctionAdaptorType::Pointer LHadaptedFunction = LHImageFunctionAdaptorType::New();
+  //std::cout << LHadaptedFunction << std::endl;
+ 
+  return EXIT_SUCCESS;
+}
+
+int otbImageFunctionAdaptor(int argc, char * argv[])
+{
+  const char * inputFilename  = argv[1];
+  
+  typedef double InputPixelType;
+  const unsigned int Dimension = 2;
+  unsigned int rsltIdx = 0;
+
+  typedef otb::Image<InputPixelType,  Dimension>                        InputImageType;
+  typedef otb::ImageFileReader<InputImageType>                          ReaderType;
+  typedef otb::StreamingMinMaxImageFilter<InputImageType>               MinMaxFilterType;
+  
+  typedef otb::FourierMellinDescriptorsImageFunction<InputImageType>    FMDFunctionType;
+  typedef otb::RealMomentsImageFunction<InputImageType>                 RMFunctionType;
+  typedef otb::ComplexMomentsImageFunction<InputImageType>              CMFunctionType;
+  typedef otb::FlusserMomentsImageFunction<InputImageType>              FMFunctionType;
+  typedef otb::HuMomentsImageFunction<InputImageType>                   HMFunctionType;
+  typedef otb::RadiometricMomentsImageFunction<InputImageType>          RaMFunctionType;
+  typedef otb::LocalHistogramImageFunction<InputImageType>              LHFunctionType;
+
+  typedef otb::ImageFunctionAdaptor<FMDFunctionType>                                    FMDImageFunctionAdaptorType;
+  typedef otb::ImageFunctionAdaptor<RMFunctionType>                                     RMImageFunctionAdaptorType;
+  typedef otb::ImageFunctionAdaptor<CMFunctionType>                                     CMImageFunctionAdaptorType;
+  typedef otb::ImageFunctionAdaptor<FMFunctionType>                                     FMImageFunctionAdaptorType;
+  typedef otb::ImageFunctionAdaptor<HMFunctionType>                                     HMImageFunctionAdaptorType;
+  typedef otb::ImageFunctionAdaptor<RaMFunctionType>                                    RaMImageFunctionAdaptorType;
+  typedef otb::ImageFunctionAdaptor<LHFunctionType>                                     LHImageFunctionAdaptorType;
+
+  // Instantiating objects
+  ReaderType::Pointer  reader = ReaderType::New();
+  MinMaxFilterType::Pointer filter   = MinMaxFilterType::New();
+  
+  FMDFunctionType::Pointer FMDFunction = FMDFunctionType::New();
+  RMFunctionType::Pointer  RMFunction  = RMFunctionType::New();
+  CMFunctionType::Pointer  CMFunction  = CMFunctionType::New();
+  FMFunctionType::Pointer  FMFunction  = FMFunctionType::New();
+  HMFunctionType::Pointer  HMFunction  = HMFunctionType::New();
+  RaMFunctionType::Pointer RaMFunction = RaMFunctionType::New();
+  LHFunctionType::Pointer  LHFunction  = LHFunctionType::New();
+
+  FMDImageFunctionAdaptorType::Pointer FMDadaptedFunction = FMDImageFunctionAdaptorType::New();
+  RMImageFunctionAdaptorType::Pointer  RMadaptedFunction  = RMImageFunctionAdaptorType::New();
+  CMImageFunctionAdaptorType::Pointer  CMadaptedFunction  = CMImageFunctionAdaptorType::New();
+  FMImageFunctionAdaptorType::Pointer  FMadaptedFunction  = FMImageFunctionAdaptorType::New();
+  HMImageFunctionAdaptorType::Pointer  HMadaptedFunction  = HMImageFunctionAdaptorType::New();
+  RaMImageFunctionAdaptorType::Pointer RaMadaptedFunction = RaMImageFunctionAdaptorType::New();
+  LHImageFunctionAdaptorType::Pointer  LHadaptedFunction  = LHImageFunctionAdaptorType::New();
+   
+  reader->SetFileName(inputFilename);
+  filter->SetInput(reader->GetOutput());
+  filter->Update();
+
+  InputImageType::IndexType index;
+  index[0] = 100;
+  index[1] = 100;
+  
+  // Content testing 
+  double error = 0.0;
+
+  FMDFunction->SetInputImage(reader->GetOutput());
+  FMDFunction->SetNeighborhoodRadius(5);
+  FMDFunction->SetPmax(5);
+  FMDFunction->SetQmax(5);
+  FMDFunctionType::OutputType resultFMD = FMDFunction->EvaluateAtIndex(index);
+
+  FMDadaptedFunction->SetInputImage(reader->GetOutput());
+  FMDadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5);
+  FMDadaptedFunction->GetInternalImageFunction()->SetPmax(5);
+  FMDadaptedFunction->GetInternalImageFunction()->SetQmax(5);
+  FMDImageFunctionAdaptorType::OutputType resultAdaptedFMD = FMDadaptedFunction->EvaluateAtIndex(index);
+  
+  rsltIdx = 0;
+  for (unsigned int i=0; i<=5; i++)
+    {
+    for (unsigned int j=0; j<=5; j++)
+      {
+      error += vcl_pow(vcl_abs(resultAdaptedFMD[rsltIdx] - resultFMD.at(i).at(j)), 2);
+    
+      std::cout << "resultAdaptedFMD : " << resultAdaptedFMD[rsltIdx] 
+                << "\t - resultFMD : " << resultFMD.at(i).at(j) << std::endl;
+      rsltIdx ++;
+      }
+    }
+
+  RMFunction->SetInputImage(reader->GetOutput());
+  RMFunction->SetNeighborhoodRadius(5);
+  RMFunction->SetPmax(5);
+  RMFunction->SetQmax(5);
+  RMFunctionType::OutputType resultRM = RMFunction->EvaluateAtIndex(index);
+
+  RMadaptedFunction->SetInputImage(reader->GetOutput());
+  RMadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5);
+  RMadaptedFunction->GetInternalImageFunction()->SetPmax(5);
+  RMadaptedFunction->GetInternalImageFunction()->SetQmax(5);
+  RMImageFunctionAdaptorType::OutputType resultAdaptedRM = RMadaptedFunction->EvaluateAtIndex(index);
+  
+  rsltIdx = 0;
+  for (unsigned int i=0; i<=5; i++)
+    {
+    for (unsigned int j=0; j<=5; j++)
+      {
+      error += vcl_pow(vcl_abs(resultAdaptedRM[rsltIdx] - resultRM.at(i).at(j)), 2);
+
+      std::cout << "resultAdaptedRM : " << resultAdaptedRM[rsltIdx] 
+                << "\t - resultRM : " << resultRM.at(i).at(j) << std::endl;
+      rsltIdx ++;
+      }
+    }
+
+  CMFunction->SetInputImage(reader->GetOutput());
+  CMFunction->SetNeighborhoodRadius(5);
+  CMFunction->SetPmax(5);
+  CMFunction->SetQmax(5);
+  CMFunctionType::OutputType resultCM = CMFunction->EvaluateAtIndex(index);
+
+  CMadaptedFunction->SetInputImage(reader->GetOutput());
+  CMadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5);
+  CMadaptedFunction->GetInternalImageFunction()->SetPmax(5);
+  CMadaptedFunction->GetInternalImageFunction()->SetQmax(5);
+  CMImageFunctionAdaptorType::OutputType resultAdaptedCM = CMadaptedFunction->EvaluateAtIndex(index);
+  
+  rsltIdx = 0;
+  for (unsigned int i=0; i<=5; i++)
+    {
+    for (unsigned int j=0; j<=5; j++)
+      {
+      error += vcl_pow(vcl_abs(resultAdaptedCM[rsltIdx] - resultCM.at(i).at(j).real()), 2);
+      std::cout << "resultAdaptedCM : (" << resultAdaptedCM[rsltIdx]
+                << "," << resultAdaptedCM[rsltIdx+1] << ")"
+                << "\t - resultCM : " << resultCM.at(i).at(j) << std::endl;
+      rsltIdx ++;
+      error += vcl_pow(vcl_abs(resultAdaptedCM[rsltIdx] - resultCM.at(i).at(j).imag()), 2);
+      rsltIdx ++;
+      }
+    }
+
+  FMFunction->SetInputImage(reader->GetOutput());
+  FMFunction->SetNeighborhoodRadius(5);
+  FMFunctionType::OutputType resultFM = FMFunction->EvaluateAtIndex(index);
+
+  FMadaptedFunction->SetInputImage(reader->GetOutput());
+  FMadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5);
+  FMImageFunctionAdaptorType::OutputType resultAdaptedFM = FMadaptedFunction->EvaluateAtIndex(index);
+  
+  rsltIdx = 0;
+  for (unsigned int i=0; i<11; i++)
+    {
+      error += vcl_pow(vcl_abs(resultAdaptedFM[rsltIdx] - resultFM[i]), 2);
+
+      std::cout << "resultAdaptedFM : " << resultAdaptedFM[rsltIdx] 
+                << "\t - resultFM : " << resultFM[i] << std::endl;
+      rsltIdx ++;
+    }
+
+  HMFunction->SetInputImage(reader->GetOutput());
+  HMFunction->SetNeighborhoodRadius(5);
+  HMFunctionType::OutputType resultHM = HMFunction->EvaluateAtIndex(index);
+
+  HMadaptedFunction->SetInputImage(reader->GetOutput());
+  HMadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5);
+  HMImageFunctionAdaptorType::OutputType resultAdaptedHM = HMadaptedFunction->EvaluateAtIndex(index);
+  
+  rsltIdx = 0;
+  for (unsigned int i=0; i<7; i++)
+    {
+    error += vcl_pow(vcl_abs(resultAdaptedHM[rsltIdx] - resultHM[i]), 2);
+
+    std::cout << "resultAdaptedHM : " << resultAdaptedHM[rsltIdx] 
+              << "\t - resultHM : " << resultHM[i] << std::endl;
+    rsltIdx ++;
+    }
+
+  RaMFunction->SetInputImage(reader->GetOutput());
+  RaMFunction->SetNeighborhoodRadius(5);
+  RaMFunctionType::OutputType resultRaM = RaMFunction->EvaluateAtIndex(index);
+  
+  RaMadaptedFunction->SetInputImage(reader->GetOutput());
+  RaMadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5);
+  RaMImageFunctionAdaptorType::OutputType resultAdaptedRaM = RaMadaptedFunction->EvaluateAtIndex(index);
+  
+  rsltIdx = 0;
+  for (unsigned int i=0; i<4; i++)
+    { 
+    error += vcl_pow(vcl_abs(resultAdaptedRaM[rsltIdx] - resultRaM[i]), 2);
+
+    std::cout << "resultAdaptedRaM : " << resultAdaptedRaM[rsltIdx] 
+              << "\t - resultRaM : " << resultRaM[i] << std::endl;
+    rsltIdx ++;
+    }
+
+  LHFunction->SetInputImage(reader->GetOutput());
+  LHFunction->SetNeighborhoodRadius(5);
+  LHFunction->SetNumberOfHistogramBins(64);
+  LHFunction->SetHistogramMin(filter->GetMinimum());
+  LHFunction->SetHistogramMax(filter->GetMaximum());
+  LHFunctionType::OutputType resultLH = LHFunction->EvaluateAtIndex(index);
+
+  LHadaptedFunction->SetInputImage(reader->GetOutput());
+  LHadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5);
+  LHadaptedFunction->GetInternalImageFunction()->SetNumberOfHistogramBins(64);
+  LHadaptedFunction->GetInternalImageFunction()->SetHistogramMin(filter->GetMinimum());
+  LHadaptedFunction->GetInternalImageFunction()->SetHistogramMax(filter->GetMaximum());
+  LHImageFunctionAdaptorType::OutputType resultAdaptedLH = LHadaptedFunction->EvaluateAtIndex(index);
+  
+  rsltIdx = 0;
+  for (unsigned int i=0; i<64; i++)
+    {
+    error += vcl_pow(vcl_abs( resultAdaptedLH[rsltIdx] - resultLH->GetFrequency(i)), 2);
+
+    std::cout << "resultAdaptedLH : " << resultAdaptedLH[rsltIdx]
+              << "\t - resultLH : " << resultLH->GetFrequency(i) << std::endl;
+    rsltIdx ++;
+    }
+  
+  error = vcl_sqrt(error);
+  std::cout << std::endl << "Error : " << error << std::endl
+            << std::endl;
+
+ if (error > 1E-3)
+    {
+    itkGenericExceptionMacro( << "Error = " << error
+                              << "  > 1E-9     -> TEST FAILLED" << std::endl );
+    }
+
+  return EXIT_SUCCESS;
+}
+