diff --git a/Code/FeatureExtraction/otbMetaImageFunction.h b/Code/FeatureExtraction/otbMetaImageFunction.h
index e2e85809bdbb07928b23ab1cf52c81ba975645d6..2d056fa826ca98d388f9e29b7e93dd5a627ab9bd 100644
--- a/Code/FeatureExtraction/otbMetaImageFunction.h
+++ b/Code/FeatureExtraction/otbMetaImageFunction.h
@@ -22,11 +22,21 @@
 #include "itkPoint.h"
 #include "itkVariableLengthVector.h"
 
+#include <vector>
+
 namespace otb
 {
 /** \class MetaImageFunction
- *  \brief TODO
+ *  \brief Concatenate results from multiple ImageFunction
+ *
+ *  The MetaImageFunction class allows to call multiple ImageFunction at the same location
+ *  and to concatenate their result into a single VariableLengthVector.
+ *
+ *  In the case of ImageFunction which do not produce VariableLengthVector, one can wrap these
+ *  function using the ImageFunctionAdaptor class, which will translate the image function output to
+ *  a VariableLengthVector.
  *
+ *  \ingroup ImageFunction
  */
 template <class TOutputPrecision = double, class TCoordRep = double>
 class ITK_EXPORT MetaImageFunction
@@ -54,9 +64,32 @@ public:
   typedef TOutputPrecision                            ValueType;
   typedef itk::VariableLengthVector<ValueType>        OutputType;
 
+  // Compatible functions typedefs
+  typedef Superclass                                  FunctionType;
+  typedef typename FunctionType::Pointer              FunctionPointerType;
+  typedef std::vector<FunctionPointerType>            FunctionContainerType;
+
   /** Evaluate the function at the given location */
   OutputType Evaluate(const PointType & point) const;
 
+  /** Add a new function to the functions vector */
+  void AddFunction(FunctionType * function);
+
+  /** Add a new function the functions vector (compatibility via adapters) */
+//  template <typename T1, typename T2> void AddFunction(itk::ImageFunction<T1,T2,TCoordRep> * function);
+
+  /** Clear functions vector */
+  void ClearFunctions();
+
+  /** Get the number of function registered */
+  unsigned int GetNumberOfFunctions() const;
+
+  /** Retrieve the nth function */
+  FunctionType * GetNthFunction(unsigned int index);
+
+  /** Remove the nth function */
+  void RemoveNthFunction(unsigned int index);
+
 protected:
   /** Constructor */
   MetaImageFunction();
@@ -70,6 +103,8 @@ protected:
 private:
   MetaImageFunction(const Self& ); //purposely not implemented
   void operator=(const Self& ); //purposely not implemented
+
+  FunctionContainerType m_FunctionContainer;
 };
 
 
diff --git a/Code/FeatureExtraction/otbMetaImageFunction.txx b/Code/FeatureExtraction/otbMetaImageFunction.txx
index 5f299735c352718467a4f0d4bd778d6765b7e40f..94239e2ba64cb89374e04f27b979c9bb0bd048ff 100644
--- a/Code/FeatureExtraction/otbMetaImageFunction.txx
+++ b/Code/FeatureExtraction/otbMetaImageFunction.txx
@@ -19,12 +19,15 @@
 #define __otbMetaImageFunction_txx
 
 #include "otbMetaImageFunction.h"
+#include "otbImageFunctionAdapter.h"
+
+#include <algorithm>
 
 namespace otb
 {
 template <class TOutputPrecision, class TCoordRep>
 MetaImageFunction<TOutputPrecision,TCoordRep>
-::MetaImageFunction()
+::MetaImageFunction() : m_FunctionContainer()
  {
 
  }
@@ -33,17 +36,100 @@ template <class TOutputPrecision, class TCoordRep>
 MetaImageFunction<TOutputPrecision,TCoordRep>
 ::~MetaImageFunction()
  {
+  this->ClearFunctions();
+ }
+
+template <class TOutputPrecision, class TCoordRep>
+void
+MetaImageFunction<TOutputPrecision,TCoordRep>
+::AddFunction(FunctionType * function)
+ {
+  m_FunctionContainer.push_back(function);
+ }
 
+//template <class TOutputPrecision, class TCoordRep, typename T1, typename T2>
+//void
+//MetaImageFunction<TOutputPrecision,TCoordRep>
+//::AddFunction(itk::ImageFunction<T1,T2,TCoordRep> * function)
+// {
+//  // Define the adapter
+//  typedef itk::ImageFunction<T1,T2,TCoordRep> ImageFunctionType;
+//  typedef otb::ImageFunctionAdapter<T1,ImageFunctionType,TCoordRep > AdapterType;
+//
+//  typename AdapterType::Pointer adapter = AdapterType::New();
+//  adapte
+//
+// }
+
+template <class TOutputPrecision, class TCoordRep>
+void
+MetaImageFunction<TOutputPrecision,TCoordRep>
+::ClearFunctions()
+ {
+  m_FunctionContainer.clear();
+ }
+
+template <class TOutputPrecision, class TCoordRep>
+unsigned int
+MetaImageFunction<TOutputPrecision,TCoordRep>
+::GetNumberOfFunctions() const
+ {
+  return m_FunctionContainer.size();
  }
 
+template <class TOutputPrecision, class TCoordRep>
+typename MetaImageFunction<TOutputPrecision,TCoordRep>
+::FunctionType *
+MetaImageFunction<TOutputPrecision,TCoordRep>
+::GetNthFunction(unsigned int index)
+ {
+  return m_FunctionContainer.at(index);
+ }
+
+ template <class TOutputPrecision, class TCoordRep>
+ void
+ MetaImageFunction<TOutputPrecision,TCoordRep>
+ ::RemoveNthFunction(unsigned int index)
+  {
+   typename FunctionContainerType::iterator fIt = m_FunctionContainer.begin()+index;
+   m_FunctionContainer.erase(fIt);
+  }
+
 template <class TOutputPrecision, class TCoordRep>
 typename MetaImageFunction<TOutputPrecision,TCoordRep>
 ::OutputType
 MetaImageFunction<TOutputPrecision,TCoordRep>
 ::Evaluate(const PointType & point) const
  {
+  // Build output
   OutputType resp;
 
+  // For each function
+  typename FunctionContainerType::const_iterator fIt = m_FunctionContainer.begin();
+  while(fIt != m_FunctionContainer.end())
+    {
+    // Store current size
+    unsigned int currentSize = static_cast<unsigned int>(resp.GetSize());
+
+    // Call current function evaluation
+    OutputType currentVector = (*fIt)->Evaluate(point);
+
+    // Compute current vector size
+    unsigned int currentVectorSize = static_cast<unsigned int>(currentVector.GetSize());
+
+    // Enlarge the output vector
+    resp.SetSize(currentSize + currentVectorSize,false);
+
+    // Fill the output
+    for(unsigned int i = 0; i < currentVectorSize; ++i)
+      {
+      resp.SetElement(currentSize+i,static_cast<ValueType>(currentVector[i]));
+      }
+
+    // Go to next function
+    ++fIt;
+    }
+
   return resp;
  }
 
@@ -54,6 +140,7 @@ MetaImageFunction<TOutputPrecision,TCoordRep>
 ::PrintSelf(std::ostream& os, itk::Indent indent) const
 {
   Superclass::PrintSelf(os, indent);
+  os<<indent<<"Number of image functions: "<<this->GetNumberOfFunctions()<<std::endl;
 }
 
 } // end namespace otb
diff --git a/Testing/Code/FeatureExtraction/CMakeLists.txt b/Testing/Code/FeatureExtraction/CMakeLists.txt
index ee91fba126174323a444238caaae90ed140f0f0d..560bcf869530627cf44fba8f1214cefa96728ca2 100644
--- a/Testing/Code/FeatureExtraction/CMakeLists.txt
+++ b/Testing/Code/FeatureExtraction/CMakeLists.txt
@@ -1518,6 +1518,15 @@ ADD_TEST(feTuMetaImageFunctionNew ${FEATUREEXTRACTION_TESTS16}
         otbMetaImageFunctionNew
 )
 
+ADD_TEST(feTvMetaImageFunction ${FEATUREEXTRACTION_TESTS16}
+--compare-ascii ${EPSILON_8}     
+    ${BASELINE_FILES}/feTvMetaImageFunction.txt
+    ${TEMP}/feTvMetaImageFunction.txt
+    otbMetaImageFunction
+	${INPUTDATA}/ROI_IKO_PAN_LesHalles.tif
+    ${TEMP}/feTvMetaImageFunction.txt
+    451846.014047961 5412466.57452216
+)
 
 # A enrichir
 SET(BasicFeatureExtraction_SRCS1
diff --git a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests16.cxx b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests16.cxx
index 7f6647cc38b5f499cb1317f5e65c28dafee9ef43..0b1ddb8e18db845756e4f2828bbf52142cf9ec51 100644
--- a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests16.cxx
+++ b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests16.cxx
@@ -35,4 +35,5 @@ void RegisterTests()
   REGISTER_TEST(otbImageFunctionAdapterNew);
   REGISTER_TEST(otbImageFunctionAdapter);
   REGISTER_TEST(otbMetaImageFunctionNew);
+  REGISTER_TEST(otbMetaImageFunction);
 }
diff --git a/Testing/Code/FeatureExtraction/otbMetaImageFunction.cxx b/Testing/Code/FeatureExtraction/otbMetaImageFunction.cxx
index 4c3e90ba5c9af9c3d435f49abad5875afd7241e1..fb5441ee64dcf4bc8085443f7e35c3dc8a9e2d12 100644
--- a/Testing/Code/FeatureExtraction/otbMetaImageFunction.cxx
+++ b/Testing/Code/FeatureExtraction/otbMetaImageFunction.cxx
@@ -20,8 +20,23 @@
 #endif
 
 #include "otbMetaImageFunction.h"
+#include "otbImage.h"
+#include "otbImageFileReader.h"
+#include "otbFlusserMomentsImageFunction.h"
+#include "otbImageFunctionAdapter.h"
 
-typedef otb::MetaImageFunction<> MetaImageFunctionType;
+typedef unsigned short                                                InputPixelType;
+const unsigned int Dimension =                                        2;
+
+typedef otb::Image<InputPixelType,  Dimension>                        InputImageType;
+typedef otb::ImageFileReader<InputImageType>                          ReaderType;
+typedef otb::FlusserMomentsImageFunction<InputImageType>              FlusserFunctionType;
+typedef otb::ImageFunctionAdapter<InputImageType,FlusserFunctionType> FunctionType;
+
+typedef otb::MetaImageFunction<
+        itk::NumericTraits<InputPixelType>::RealType,double>          MetaImageFunctionType;
+typedef MetaImageFunctionType::PointType                              PointType;
+typedef MetaImageFunctionType::OutputType                             OutputType;
 
 int otbMetaImageFunctionNew(int argc, char * argv[])
 {
@@ -29,3 +44,62 @@ int otbMetaImageFunctionNew(int argc, char * argv[])
 
   return EXIT_SUCCESS;
 }
+
+int otbMetaImageFunction(int argc, char * argv[])
+{
+  // Read the input image
+  ReaderType::Pointer   reader = ReaderType::New();
+  reader->SetFileName(argv[1]);
+  reader->Update();
+
+  // Build  flusser functions with different radius
+  FunctionType::Pointer function1 = FunctionType::New();
+  FunctionType::Pointer function2 = FunctionType::New();
+  FunctionType::Pointer function3 = FunctionType::New();
+
+  function1->SetInputImage(reader->GetOutput());
+  function2->SetInputImage(reader->GetOutput());
+  function3->SetInputImage(reader->GetOutput());
+
+  function1->GetImageFunction()->SetNeighborhoodRadius(3);
+  function2->GetImageFunction()->SetNeighborhoodRadius(5);
+  function3->GetImageFunction()->SetNeighborhoodRadius(7);
+
+  std::ofstream outputStream(argv[2]);
+
+  MetaImageFunctionType::Pointer metaFunction = MetaImageFunctionType::New();
+  metaFunction->AddFunction(function1);
+  metaFunction->AddFunction(function2);
+  metaFunction->AddFunction(function3);
+
+  outputStream<<"Initial number of functions: "<<metaFunction->GetNumberOfFunctions()<<std::endl;
+
+  metaFunction->RemoveNthFunction(2);
+
+  outputStream<<"Number of functions after removing the 2nd: "<<metaFunction->GetNumberOfFunctions()<<std::endl;
+
+  metaFunction->ClearFunctions();
+
+  outputStream<<"Number of functions after clear: "<<metaFunction->GetNumberOfFunctions()<<std::endl;
+
+  metaFunction->AddFunction(function1);
+  metaFunction->AddFunction(function2);
+  metaFunction->AddFunction(function3);
+
+  outputStream<<"Adding functions again: "<<metaFunction->GetNumberOfFunctions()<<std::endl;
+
+  // For coverage
+  metaFunction->GetNthFunction(0);
+
+  PointType p;
+  p[0] = atof(argv[3]);
+  p[1] = atof(argv[4]);
+
+  OutputType output = metaFunction->Evaluate(p);
+
+  outputStream<<"Evaluate("<<p<<") = "<<output<<std::endl;
+
+  outputStream.close();
+
+  return EXIT_SUCCESS;
+}