diff --git a/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.h b/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4f07d5c65c38451167faae287919c52f21f7285
--- /dev/null
+++ b/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.h
@@ -0,0 +1,100 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+  Copyright (c) Institut Telecom / Telecom Bretagne. All rights reserved. 
+  See ITCopyright.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.
+
+=========================================================================*/
+
+#ifndef __otbEuclideanDistanceWithMissingValue_h
+#define __otbEuclideanDistanceWithMissingValue_h
+
+#include <itkEuclideanDistance.h>
+
+namespace otb {
+
+namespace Statistics {
+
+/** \class EuclideanDistanceWithMissingValue
+ * \brief Euclidean distance function facing missing value.
+ *
+ * This class is derived from EuclideanDistance class. In addition 
+ * to the initial Evaluate method, the class does not perform calculation
+ * when a component does not contain any data.
+ * 
+ * The class can be templated over any container that holds data elements, as
+ * for template of EuclideanDistance. 
+ *
+ * The only restriction is that elemnts have to support '\code{NaN}'.
+ *
+ * \sa EuclideanDistance
+ */
+template< class TVector >
+class ITK_EXPORT EuclideanDistanceWithMissingValue :
+	public itk::Statistics::EuclideanDistance< TVector >
+{
+	public:
+		/** Standard "Self" typedef. */
+		typedef EuclideanDistanceWithMissingValue Self;
+		typedef itk::Statistics::EuclideanDistance< TVector > Superclass;
+		typedef itk::SmartPointer< Self > Pointer ; 
+		typedef itk::SmartPointer<const Self> ConstPointer;
+		typedef typename Superclass::MeasurementVectorSizeType MeasurementVectorSizeType;
+
+		/** Run-time type information (and related methods). */
+		itkTypeMacro(EuclideanDistanceWithMissingValue, EuclideanDistance);
+
+		/** Method for creation through the object factory. */
+		itkNewMacro(Self) ;
+
+		/** Type of the component of a vector */
+		typedef typename TVector::ValueType ValueType ;
+
+		/** Gets the distance between the origin and x */
+		double Evaluate(const TVector &x) const ;
+
+		/** Gets the distance between x1 and x2 */
+		double Evaluate(const TVector &x1, const TVector &x2) const ;
+
+		/** Gets the cooridnate distance between a and b. NOTE: a and b
+		* should be type of component */ 
+		double Evaluate(const ValueType &a, const ValueType &b) const ;
+
+		/** Returns true if the distance between x and the origin is less
+		* than radius */
+		bool IsWithinRange(const TVector &x, const double radius) const {
+			return Superclass::IsWithinRange( x, radius ); }
+
+		/** Check if a value is NaN or not */
+		static bool IsMissingValue ( const ValueType & v) ;
+
+		/** Set a value to Nan */
+		static void SetToMissingValue ( ValueType & v );
+
+	protected:
+		EuclideanDistanceWithMissingValue() {}
+		virtual ~EuclideanDistanceWithMissingValue() {} 
+} ; // end of class
+
+} // end namespace statistics
+
+} // end namespace otb
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "otbEuclideanDistanceWithMissingValue.txx"
+#endif
+
+#endif
+
diff --git a/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.txx b/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.txx
new file mode 100644
index 0000000000000000000000000000000000000000..70e7db1f5780dbd45bb97499f42775f39cd38a5b
--- /dev/null
+++ b/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.txx
@@ -0,0 +1,149 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+  Copyright (c) Institut Telecom / Telecom Bretagne. All rights reserved. 
+  See ITCopyright.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.
+
+=========================================================================*/
+
+#ifndef __otbEuclideanDistanceWithMissingValue_txx
+#define __otbEuclideanDistanceWithMissingValue_txx
+
+#include "itkNumericTraits.h"
+
+namespace otb {
+
+namespace Statistics {
+
+template< class TVector >
+inline double
+EuclideanDistanceWithMissingValue< TVector >
+::Evaluate(const TVector &x1, const TVector &x2) const
+{
+	if( itk::MeasurementVectorTraits::GetLength( x1 ) != 
+		itk::MeasurementVectorTraits::GetLength( x2 ) )
+	{
+		itkExceptionMacro( << "Vector lengths must be equal." );
+	}
+
+	double temp, distance = itk::NumericTraits< double >::Zero ;
+
+	for(unsigned int i = 0 ; i < x1.Size(); i++ )
+	{
+		if ( !IsMissingValue( x1[i] ) && !IsMissingValue( x2[i] ) )
+		{
+			temp = x1[i] - x2[i] ;
+			distance += temp * temp ;
+		}
+	}
+
+	return ::vcl_sqrt(distance) ;
+}
+
+template< class TVector >
+inline double
+EuclideanDistanceWithMissingValue< TVector >
+::Evaluate(const TVector &x) const
+{
+	MeasurementVectorSizeType 
+		measurementVectorSize = this->GetMeasurementVectorSize();
+	if(measurementVectorSize == 0) 
+	{
+		itkExceptionMacro( << "Please set the MeasurementVectorSize first" );
+	}
+	itk::MeasurementVectorTraits::Assert( this->m_Origin, measurementVectorSize, 
+		"EuclideanDistance::Evaluate Origin and input vector have different lengths");
+
+	double temp, distance = itk::NumericTraits< double >::Zero ;
+
+	for(unsigned int i = 0 ; i < measurementVectorSize ; i++ )
+	{
+		if ( !IsMissingValue( this->GetOrigin()[i] ) && !IsMissingValue( x[i] ) )
+		{
+			temp = this->GetOrigin()[i] - x[i] ;
+			distance += temp * temp ;
+		}
+	}
+
+	return ::vcl_sqrt(distance) ;
+}
+
+template< class TVector >
+inline double
+EuclideanDistanceWithMissingValue< TVector >
+::Evaluate( const ValueType &a, const ValueType &b ) const
+{
+	// FIXME throw NaN exception ??
+	if ( IsMissingValue( a ) || IsMissingValue( b ) )
+		return 0.0;
+
+	double temp = a - b ;
+	return ::vcl_sqrt(temp * temp) ;
+}
+
+#if defined(_MSC_VER) /* Microsoft Visual C++ */
+#include <float.h>
+
+template< class TVector >
+/*static */
+bool
+EuclideanDistanceWithMissingValue< TVector >
+::IsMissingValue ( const ValueType & v) 
+{
+	return static_cast<bool>( _isnan( const_cast<double>( v ) ) ); 
+}
+
+#elif HAVE_IEEE_COMPARISONS
+
+template< class TVector >
+/*static */
+bool
+EuclideanDistanceWithMissingValue< TVector >
+::IsMissingValue ( const ValueType & v) 
+{
+	return (v!=v);
+}
+
+#else
+
+template< class TVector >
+/*static */
+bool
+EuclideanDistanceWithMissingValue< TVector >
+::IsMissingValue ( const ValueType & v) 
+{
+	return static_cast<bool>( isnan(v) );
+}
+
+#endif 
+
+template< class TVector >
+/* static */
+void
+EuclideanDistanceWithMissingValue< TVector >
+::SetToMissingValue ( ValueType & v )
+{
+	v = static_cast<ValueType>( 0.0/0.0 );
+}
+
+
+} // end namespace statistics
+
+} // end namespace otb
+
+#endif
+
+
+
diff --git a/Code/Learning/otbCzihoSOMLearningBehaviorFunctor.h b/Code/Learning/otbCzihoSOMLearningBehaviorFunctor.h
new file mode 100644
index 0000000000000000000000000000000000000000..44260ab8183fb267e4d0ed67362daa3731ea9294
--- /dev/null
+++ b/Code/Learning/otbCzihoSOMLearningBehaviorFunctor.h
@@ -0,0 +1,110 @@
+/*=========================================================================
+
+Program:   ORFEO Toolbox
+Language:  C++
+Date:      $Date$
+Version:   $Revision$
+
+
+Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+See OTBCopyright.txt for details.
+
+Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. 
+See ITCopyright.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.
+
+=========================================================================*/
+
+#ifndef __otbCzihoSOMLearningBehaviorFunctor_h
+#define __otbCzihoSOMLearningBehaviorFunctor_h
+
+#include "itkSize.h"
+
+namespace otb {
+
+namespace Functor {
+
+	/** \class CzihoSOMLearningBehaviorFunctor
+	* \brief Beta behavior over SOM training phase
+	*
+	*	This class implements an evolution of the \f$ \beta \f$ weightening
+	*	coefficient over the SOM training. It is issued from A. Cziho's PhD:
+	*	"Compression d'images et analyse de contenu par quantification vectorielle"
+	*	PhD dissertation, University of Rennes I, Rennes, France. May 5th, 1999.
+	*
+	*	Its behavior is decomposed into two steps depending on the number of iterations:
+	*	\f{equation*}
+			\beta = \begn{cases}
+				\beta_0 \left( 1 - \frac{t}{t_0} \right) & \text{ if $t < t_0$} \\
+				\beta_{\text{end}} \left( 1- \frac{t-t_O}{t_{\text{end}}-t_0} \right) 
+					& \text{ if $ t_0 \leqslant t < t_{\text{end}}$}
+			\end{cases}
+		\f{equation*}
+		where \f$ t_0 \f$ stands for IterationThreshold.
+	*
+	*	CzihoSOMLearningBehaviorFunctor uses some parameters of the SOM class such as:
+	*	BetaInit, BetaEnd, NumberOfIterations, but also NeighborhoodSizeInit which may be 
+	*	(surprisingly) required for the IterationThreshold.
+	*
+	*	The functor function uses \code{NumberOfIterations}, \code{BetaInit}, \code{BetaEnd} parameters, that is 
+	*	why it is necessary to call a specific method for \code{IterationThreshold} intialisation.
+	*
+	*	\sa SOM
+	*/
+	class CzihoSOMLearningBehaviorFunctor
+	{
+		public :
+			/** Empty constructor / descructor */
+			CzihoSOMLearningBehaviorFunctor () { m_IterationThreshold = 0; }
+			virtual ~CzihoSOMLearningBehaviorFunctor() { }
+
+			/** Accessors */
+			unsigned int GetIterationThreshold () { return this->m_IterationThreshold; }
+
+			template < unsigned int VDimension >
+			void SetIterationThreshold ( const itk::Size<VDimension> & sizeInit, unsigned int iterMax ) 
+			{
+				double V0 = static_cast<double>( sizeInit[0] );
+				for ( int i = 1; i < VDimension; i++ )
+				{
+					if ( V0 < static_cast<double>( sizeInit[i] ) )
+						V0 = static_cast<double>( sizeInit[i] );
+				}
+					
+				m_IterationThreshold = static_cast<unsigned int>(
+					static_cast<double>( iterMax ) * ( 1.0 - 1.0 / ::vcl_sqrt( V0 ) ) );
+			}
+
+			/** Functor */
+			virtual double operator() ( unsigned int currentIteration, 
+										unsigned int numberOfIterations,
+										double betaInit, double betaEnd )
+			{
+				if ( currentIteration < m_IterationThreshold )
+				{
+					return betaInit * ( 1.0 
+							- static_cast<double>( currentIteration )
+								/ static_cast<double>(  numberOfIterations ) );
+				}
+				else
+				{
+					return betaEnd * ( 1.0 
+							- static_cast<double>( currentIteration - m_IterationThreshold )
+							/ static_cast<double>(  numberOfIterations - m_IterationThreshold ) );
+				}
+			}
+
+		private:
+			unsigned int m_IterationThreshold;
+
+	}; // end of class CzihoSOMLearningBehaviorFunctor
+
+} // end namespace Functor
+
+} // end namespace otb
+
+#endif
+
diff --git a/Code/Learning/otbCzihoSOMNeighborhoodBehaviorFunctor.h b/Code/Learning/otbCzihoSOMNeighborhoodBehaviorFunctor.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d94c90ce9377584ede2153675364155c93ac996
--- /dev/null
+++ b/Code/Learning/otbCzihoSOMNeighborhoodBehaviorFunctor.h
@@ -0,0 +1,82 @@
+/*=========================================================================
+
+Program:   ORFEO Toolbox
+Language:  C++
+Date:      $Date$
+Version:   $Revision$
+
+
+Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+See OTBCopyright.txt for details.
+
+Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. 
+See ITCopyright.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.
+
+=========================================================================*/
+
+#ifndef __otbCzihoSOMNeighborhoodBehaviorFunctor_h
+#define __otbCzihoSOMNeighborhoodBehaviorFunctor_h
+
+
+namespace otb {
+
+namespace Functor {
+
+	/** \class CzihoSOMNeighborhoodBehaviorFunctor
+	*	\brief Neighborhood size behavior over SOM training phase
+	*
+	*	This class implements an evolution of the neighborhood size
+	*	over the SOM training. It is issued from A. Cziho's PhD:
+	*	"Compression d'images et analyse de contenu par quantification vectorielle"
+	*	PhD dissertation, University of Rennes I, Rennes, France. May 5th, 1999.
+	*
+	*	The behavior of the radius r (\em ie. \code{SizeType} component 0, 1,...) is given by:
+	*	\f{equation*}
+			r = r_{\text{init}} \left( 1 - \frac{t}{t_{\text{end}}} \right)^2
+		\f{equation*}
+	*
+	*	CzihoSOMNeighborhoodBehaviorFunctor uses some parameters of the SOM class such as:
+	*	\code{NeighborhoodSizeInit}, \code{NumberOfIterations} which are parameters of the functor function.
+	*	\code{operator()} is templated with the dimension of the neighborhoodSize.
+	*
+	*	\sa SOM
+	*/
+	class CzihoSOMNeighborhoodBehaviorFunctor
+	{
+		public :
+			/** Empty constructor / descructor */
+			CzihoSOMNeighborhoodBehaviorFunctor () { }
+			virtual ~CzihoSOMNeighborhoodBehaviorFunctor() { }
+
+			/** Functor */
+			template < unsigned int VDimension >
+			itk::Size<VDimension> operator() ( unsigned int currentIteration, 
+											unsigned int numberOfIterations,
+											const itk::Size<VDimension> & sizeInit )
+			{
+				itk::Size<VDimension> theSize;
+				double weightening = ::vcl_pow( 1.0 
+										- static_cast<double>( currentIteration )
+											/ static_cast<double>( numberOfIterations ),
+											2.0 );
+				for (unsigned int i = 0; i < VDimension; i++ )
+				{
+					theSize[i] = static_cast<typename itk::Size<VDimension>::SizeValueType> ( 
+									static_cast<double>( sizeInit[i] ) * weightening );
+				}
+
+				return theSize;
+			}
+
+	}; // end of class CzihoSOMNeighborhoodBehaviorFunctor
+
+} // end namespace Functor
+
+} // end namespace otb
+
+#endif
+
diff --git a/Code/Learning/otbPeriodicSOM.h b/Code/Learning/otbPeriodicSOM.h
new file mode 100644
index 0000000000000000000000000000000000000000..682c5419be32362523fd3976daa6ca3ee2043218
--- /dev/null
+++ b/Code/Learning/otbPeriodicSOM.h
@@ -0,0 +1,130 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+  Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. 
+  See ITCopyright.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.
+
+=========================================================================*/
+
+#ifndef __otbPeriodicSOM_h
+#define __otbPeriodicSOM_h
+
+#include "otbSOM.h"
+
+namespace otb {
+
+/**
+ * \class PeriodicSOM
+ * \brief This class is responsible for the learning of a self organizing 
+ * map when considered to as a torus.
+ *
+ * This class extends the SOM object which implements the Self 
+ * Organizing Map (or Kohonen map) learning.
+ * 
+ * The learning process iteratively select the best-response neuron for each input vector,
+ * enhancing its response and the response of its neighbors with respect to a certain radius, 
+ * computed from an initial radius, and to a certain learning factor, decreasing at each iteration.
+ *
+ * The behavior of the neighborhood is given by a functor (templated) which parameter is the current
+ * iteration. It returns a neighborhood of type \code{SizeType}.
+ *
+ * The behavior of the learning factor (hold by a beta variable) is given by an other functor 
+ * which parameter is the current iteration. It returns a beta value of type \code{double}.
+ *
+ * The SOMMap produced as output can be either initialized with a constant custom value or randomly 
+ * generated following a normal law. The seed for the random intialization can be modified.
+ *
+ * \sa SOMMap
+ * \sa SOMActivationBuilder
+ * \sa CzihoSOMLearningBehaviorFunctor
+ * \sa CzihoSOMNeighborhoodBehaviorFunctor
+ */
+template <class TListSample, class TMap,
+		 class TSOMLearningBehaviorFunctor = Functor::CzihoSOMLearningBehaviorFunctor, 
+		 class TSOMNeighborhoodBehaviorFunctor = Functor::CzihoSOMNeighborhoodBehaviorFunctor > 
+class ITK_EXPORT PeriodicSOM  
+	: public SOM< TListSample, TMap, TSOMLearningBehaviorFunctor, TSOMNeighborhoodBehaviorFunctor >
+{
+public:
+	/** Standard typedefs */
+	typedef PeriodicSOM Self;
+	typedef SOM< TListSample, TMap, 
+					TSOMLearningBehaviorFunctor, 
+					TSOMNeighborhoodBehaviorFunctor > Superclass;
+	typedef itk::SmartPointer<Self> Pointer;
+	typedef itk::SmartPointer<const Self> ConstPointer;
+
+	/** Creation through object factory macro */
+	itkNewMacro(Self);
+
+	/** Runtime informations macro */
+	itkTypeMacro( PeriodicSOM, SOM );
+
+	typedef TListSample ListSampleType;
+	typedef typename ListSampleType::Pointer ListSamplePointerType;
+	typedef TMap MapType;
+	typedef typename MapType::PixelType NeuronType;
+	typedef typename NeuronType::ValueType ValueType;
+	typedef typename MapType::IndexType IndexType;
+	typedef typename MapType::SizeType SizeType;
+	typedef typename MapType::RegionType RegionType;
+	typedef typename MapType::Pointer MapPointerType;
+
+protected:
+	/** Constructor */
+	PeriodicSOM() {}
+	/** Destructor */
+	virtual ~PeriodicSOM() {}
+	/** Output information redefinition */
+	virtual void GenerateOutputInformation () {
+	  	Superclass::GenerateOutputInformation (); }
+	/** Output allocation redefinition */
+	virtual void AllocateOutputs() {
+	  	Superclass::AllocateOutputs(); }
+	/** Main computation method */
+	virtual void GenerateData(void) {
+		Superclass::GenerateData(); }
+	/**
+	* Update the output map with a new sample.
+	* \param sample The new sample to learn,
+	* \param beta The learning coefficient,
+	* \param radius The radius of the nieghbourhood.
+	*/
+	virtual void UpdateMap(const NeuronType& sample, double beta, SizeType& radius);
+	/**
+	* Step one iteration.
+	*/
+	virtual void Step(unsigned int currentIteration) {
+		Superclass::Step( currentIteration ); }
+	/** PrintSelf method */
+	void PrintSelf(std::ostream& os, itk::Indent indent) const {
+		Superclass::PrintSelf(os,indent); }
+
+private:
+	PeriodicSOM(const Self&); // purposely not implemented 
+	void operator=(const Self&); // purposely not implemented 
+
+}; // end of class
+
+} // end of namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbPeriodicSOM.txx"
+#endif
+
+#endif
+
+
+
diff --git a/Code/Learning/otbPeriodicSOM.txx b/Code/Learning/otbPeriodicSOM.txx
new file mode 100644
index 0000000000000000000000000000000000000000..c4811314d836cfb1a0dd5b69d14255bc5425db3e
--- /dev/null
+++ b/Code/Learning/otbPeriodicSOM.txx
@@ -0,0 +1,109 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+  Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved.
+  See ITCopyright.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.
+
+=========================================================================*/
+
+#ifndef __otbPeriodicSOM_txx
+#define __otbPeriodicSOM_txx
+
+#include <itkNumericTraits.h>
+#include <itkNeighborhoodIterator.h>
+
+#include "otbPeriodicSOM.h"
+
+
+namespace otb {
+
+/**
+ * Update the output map with a new sample.
+ * \param sample The new sample to learn,
+ * \param beta The learning coefficient,
+ * \param radius The radius of the nieghbourhood.
+ */
+template < class TListSample, class TMap,
+	class TSOMLearningBehaviorFunctor,
+	class TSOMNeighborhoodBehaviorFunctor >
+void
+PeriodicSOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor>
+::UpdateMap(const NeuronType& sample, double beta, SizeType& radius)
+{
+	unsigned int i,j;
+
+	// output map pointer
+	MapPointerType map = this->GetOutput(0);
+
+	// winner index in the map
+	IndexType position = map->GetWinner(sample);
+	NeuronType winner = map->GetPixel(position);
+
+	// Local neighborhood definition
+	typedef typename MapType::Superclass ImageMapType;
+	typedef itk::NeighborhoodIterator< ImageMapType > NeighborhoodIteratorType;
+	typename MapType::RegionType mapRegion = map->GetLargestPossibleRegion();
+	NeighborhoodIteratorType it ( radius, map, mapRegion );
+
+	// Here, the periodic update is achieved 'by hand' since 
+	// PeriodicBoundaryCondition does not allow to modifiy
+	// VectorImage contents
+	SizeType mapSize = mapRegion.GetSize();
+	IndexType positionToUpdate;
+
+	// Iterate over the neighborhood ot the winner neuron
+	it.SetLocation( position );
+
+	for ( i = 0; i < it.Size(); i++ )
+	{
+		typename NeighborhoodIteratorType::OffsetType offset = it.GetOffset(i);
+		
+		// The neighborhood is of elliptic shape
+		double theDistance = itk::NumericTraits< double >::Zero;
+		for ( j = 0; j < MapType::ImageDimension; j++ )
+			theDistance += pow( static_cast<double>( offset[j] ), 2.0 )
+							/ pow( static_cast<double>( radius[j] ), 2.0 );
+
+		if ( theDistance <= 1.0 )
+		{
+			for ( j = 0; j < MapType::ImageDimension; j++ )
+			{
+				int pos = offset[j] + position[j];
+				positionToUpdate[j] = ( pos >= 0 ) ? 
+					pos % mapSize[j] :
+					( mapSize[j] - ( (-pos) % mapSize[j] ) ) % mapSize[j];
+			}
+
+			NeuronType tempNeuron = it.GetPixel(i);
+			// NeuronType newNeuron ( tempNeuron.Size() );
+			// newNeuron.Fill( 0.0 ); // FIXME
+			NeuronType newNeuron ( tempNeuron );
+
+			double tempBeta = beta / ( 1.0 + theDistance );
+			for( j = 0; j < newNeuron.Size(); j++ )
+			{
+				newNeuron[j] += static_cast<typename NeuronType::ValueType>(
+									( sample[j] - tempNeuron[j] ) * tempBeta );
+			}
+			map->SetPixel(positionToUpdate,newNeuron);
+		}
+	}
+
+}
+
+} // end of namespace otb
+
+#endif
+
diff --git a/Code/Learning/otbSOM.h b/Code/Learning/otbSOM.h
index 7048ff1302b49c9d087b8d69e10036d8240e143b..bcdbcec6f4917e414f0572c82bbe4d29e6cfa0d3 100644
--- a/Code/Learning/otbSOM.h
+++ b/Code/Learning/otbSOM.h
@@ -9,6 +9,8 @@ Version:   $Revision$
 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.
 
+Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. 
+See ITCopyright.txt for details.
 
 This software is distributed WITHOUT ANY WARRANTY; without even 
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
@@ -21,6 +23,9 @@ PURPOSE.  See the above copyright notices for more information.
 #include "itkImageToImageFilter.h"
 #include "itkEuclideanDistance.h"
 
+#include "otbCzihoSOMLearningBehaviorFunctor.h"
+#include "otbCzihoSOMNeighborhoodBehaviorFunctor.h"
+
 namespace otb
 {
 /**
@@ -32,13 +37,23 @@ namespace otb
  * enhancing its response and the response of its neighbors with respect to a certain radius, 
  * computed from an initial radius, and to a certain learning factor, decreasing at each iteration.
  *
+ * The behavior of the neighborhood is given by a functor (templated) which parameter is the current
+ * iteration. It returns a neighborhood of type \code{SizeType}.
+ *
+ * The behavior of the learning factor (hold by a beta variable) is given by an other functor 
+ * which parameter is the current iteration. It returns a beta value of type double.
+ *
  * The SOMMap produced as output can be either initialized with a constant custom value or randomly 
  * generated following a normal law. The seed for the random intialization can be modified.
  *
  * \sa SOMMap
  * \sa SOMActivationBuilder
+ * \sa CzihoSOMLearningBehaviorFunctor
+ * \sa CzihoSOMNeighborhoodBehaviorFunctor
  */
-template <class TListSample,class TMap>  
+template < class TListSample, class TMap, 
+		 class TSOMLearningBehaviorFunctor = Functor::CzihoSOMLearningBehaviorFunctor, 
+		 class TSOMNeighborhoodBehaviorFunctor = Functor::CzihoSOMNeighborhoodBehaviorFunctor >
 class ITK_EXPORT SOM  
 : public itk::ImageSource<TMap>
 {
@@ -64,6 +79,9 @@ class ITK_EXPORT SOM
   typedef typename MapType::RegionType RegionType;
   typedef typename MapType::Pointer MapPointerType;
   
+  typedef TSOMLearningBehaviorFunctor SOMLearningBehaviorFunctorType;
+  typedef TSOMNeighborhoodBehaviorFunctor SOMNeighborhoodBehaviorFunctorType;
+
   /** Map dimension */
   itkStaticConstMacro(MapDimension,unsigned int, MapType::ImageDimension);
   
@@ -89,24 +107,34 @@ class ITK_EXPORT SOM
   itkGetObjectMacro(ListSample,ListSampleType);
   itkSetObjectMacro(ListSample,ListSampleType);
 
+  void SetBetaFunctor ( const SOMLearningBehaviorFunctorType & functor ) {
+	  m_BetaFunctor = functor; }
+
+  void SetNeighborhoodSizeFunctor ( const SOMNeighborhoodBehaviorFunctorType & functor ) {
+	  m_NeighborhoodSizeFunctor = functor; }
+
   protected:
   /** Constructor */
   SOM();
   /** Destructor */
   virtual ~SOM();
+  /** Output information redefinition */
+  virtual void GenerateOutputInformation ();
+  /** Output allocation redefinition */
+  virtual void AllocateOutputs();
   /** Main computation method */
-  void GenerateData(void);
+  virtual void GenerateData(void);
   /**
    * Update the output map with a new sample.
    * \param sample The new sample to learn,
    * \param beta The learning coefficient,
    * \param radius The radius of the nieghbourhood.
    */
-  void UpdateMap(const NeuronType& sample, double beta, SizeType& radius);
+  virtual void UpdateMap(const NeuronType& sample, double beta, SizeType& radius);
   /**
    * Step one iteration.
    */
-  void Step(unsigned int currentIteration);  
+  virtual void Step(unsigned int currentIteration);  
   /** PrintSelf method */
   void PrintSelf(std::ostream& os, itk::Indent indent) const;
   
@@ -133,6 +161,10 @@ class ITK_EXPORT SOM
   unsigned int m_Seed;
   /** The input list sample */
   ListSamplePointerType m_ListSample;
+  /** Behavior of the Learning weightening (link to the beta coefficient) */
+  SOMLearningBehaviorFunctorType m_BetaFunctor;
+  /** Behavior of the Neighborhood extent */
+  SOMNeighborhoodBehaviorFunctorType m_NeighborhoodSizeFunctor;
 
 };
 } // end namespace otb
diff --git a/Code/Learning/otbSOM.txx b/Code/Learning/otbSOM.txx
index abbed6dd109372f6e26fc72f43fcebc78d97a72c..177fe1ea2f3e0aa200e10ad7d46eaf32c44d013b 100644
--- a/Code/Learning/otbSOM.txx
+++ b/Code/Learning/otbSOM.txx
@@ -9,6 +9,9 @@ Version:   $Revision$
 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.
 
+Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. 
+See ITCopyright.txt for details.
+
 
 This software is distributed WITHOUT ANY WARRANTY; without even 
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
@@ -31,8 +34,10 @@ namespace otb
 /** 
  * Constructor 
  */
-template <class TListSample,class TMap>  
-SOM<TListSample,TMap>
+template < class TListSample, class TMap,
+	class TSOMLearningBehaviorFunctor,
+	class TSOMNeighborhoodBehaviorFunctor >  
+SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor>
 ::SOM()
 {
   this->SetNumberOfRequiredInputs(0);
@@ -51,8 +56,10 @@ SOM<TListSample,TMap>
 /** 
  * Destructor 
  */
-template <class TListSample,class TMap>  
-SOM<TListSample,TMap>
+template < class TListSample, class TMap,
+	class TSOMLearningBehaviorFunctor,
+	class TSOMNeighborhoodBehaviorFunctor > 
+SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor>
 ::~SOM()
 {
 }
@@ -62,138 +69,195 @@ SOM<TListSample,TMap>
  * \param beta The learning coefficient,
  * \param radius The radius of the nieghbourhood.
  */
-template <class TListSample,class TMap>  
+template < class TListSample, class TMap,
+	class TSOMLearningBehaviorFunctor,
+	class TSOMNeighborhoodBehaviorFunctor >
 void
-SOM<TListSample,TMap>
-::UpdateMap(const NeuronType& sample, double beta, SizeType& radius)
+SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor>
+::UpdateMap( const NeuronType& sample, double beta, SizeType& radius )
 {
-  // output map pointer
-  MapPointerType map = this->GetOutput();
-
-  // typedefs
-  typedef itk::ImageRegionIteratorWithIndex<MapType> IteratorType;
-  typedef itk::ContinuousIndex<double,MapType::ImageDimension> ContinuousIndexType;
-  typedef itk::Statistics::EuclideanDistance<ContinuousIndexType> DistanceType; 
-  typename DistanceType::Pointer distance = DistanceType::New();
-
-  // winner index in the map
-  IndexType position = map->GetWinner(sample);
-  NeuronType winner = map->GetPixel(position);
-
-  // Local neighborhood definition
-  RegionType localRegion;
-  IndexType  localIndex = position-radius;
-  SizeType   localSize;
-  for(unsigned int i=0;i<MapType::ImageDimension;++i)
-    {
-      localSize[i]= 2*radius[i]+1;
-    }
-  localRegion.SetIndex(localIndex);
-  localRegion.SetSize(localSize);
-  localRegion.Crop(map->GetLargestPossibleRegion());
-  IteratorType it(map,localRegion);
-
-  // Walk through the map, and evolve each neuron depending on its 
-  // distance to the winner.
-  for(it.GoToBegin();!it.IsAtEnd();++it)
-    {
-      NeuronType tempNeuron = it.Get();
-      NeuronType newNeuron;
-      double tempBeta = beta/(1+distance->Evaluate(ContinuousIndexType(position),ContinuousIndexType(it.GetIndex())));
-      for(unsigned int i = 0; i<NeuronType::Length;++i)
+	// output map pointer
+	MapPointerType map = this->GetOutput(0);
+
+	// typedefs
+	typedef itk::ImageRegionIteratorWithIndex<MapType> IteratorType;
+	typedef itk::ContinuousIndex<double,MapType::ImageDimension> ContinuousIndexType;
+	typedef itk::Statistics::EuclideanDistance<ContinuousIndexType> DistanceType; 
+	typename DistanceType::Pointer distance = DistanceType::New();
+
+	// winner index in the map
+	IndexType position = map->GetWinner(sample);
+	NeuronType winner = map->GetPixel(position);
+
+	// Local neighborhood definition
+	RegionType localRegion;
+	IndexType  localIndex = position-radius;
+	SizeType   localSize;
+	for(unsigned int i=0;i<MapType::ImageDimension;++i)
+	{
+		localSize[i]= 2*radius[i]+1;
+	}
+	localRegion.SetIndex(localIndex);
+	localRegion.SetSize(localSize);
+	localRegion.Crop( map->GetLargestPossibleRegion() );
+	IteratorType it ( map, localRegion );
+
+	// Walk through the map, and evolve each neuron depending on its 
+	// distance to the winner.
+	for(it.GoToBegin();!it.IsAtEnd();++it)
 	{
-	 newNeuron[i] = tempNeuron[i]+static_cast<typename NeuronType::ValueType>((sample[i]-tempNeuron[i])*tempBeta);
+		NeuronType tempNeuron = it.Get();
+		NeuronType newNeuron ( tempNeuron.Size() );
+		double tempBeta = beta
+						/ ( 1 + 
+							distance->Evaluate( ContinuousIndexType(position),
+												ContinuousIndexType(it.GetIndex()) ) );
+
+		for(unsigned int i = 0; i < newNeuron.Size();++i)
+		{
+			newNeuron[i] = tempNeuron[i]
+							+static_cast<typename NeuronType::ValueType>(
+										( sample[i] - tempNeuron[i] ) * tempBeta );
+		}
+
+		it.Set(newNeuron);
 	}
-      it.Set(newNeuron);
-    }
 }
 /**
  * Step one iteration.
  */
-template <class TListSample,class TMap>  
+template < class TListSample, class TMap,
+	class TSOMLearningBehaviorFunctor,
+	class TSOMNeighborhoodBehaviorFunctor >
 void 
-SOM<TListSample,TMap>
+SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor>
 ::Step(unsigned int currentIteration)
 {  
-  // Compute the new learning coefficient
-  double newBeta = (m_BetaEnd-m_BetaInit)/static_cast<double>(m_NumberOfIterations)
-    *static_cast<double>(currentIteration)+m_BetaInit;
-
-  // Compute the new neighborhood size
-  SizeType newSize;
-  newSize[0]=m_NeighborhoodSizeInit[0]-static_cast<int>((static_cast<float>(currentIteration)
-  /static_cast<float>(m_NumberOfIterations))*static_cast<float>(m_NeighborhoodSizeInit[0]-2));
-
-  newSize[1]=m_NeighborhoodSizeInit[1]-static_cast<int>((static_cast<float>(currentIteration)
-  /static_cast<float>(m_NumberOfIterations))*static_cast<float>(m_NeighborhoodSizeInit[1]-2));
-
- // update the neurons map with each example of the training set.
-  otbMsgDebugMacro(<<"Beta: "<<newBeta<<", radius: "<<newSize);
- for(typename ListSampleType::Iterator it=m_ListSample->Begin();it!=m_ListSample->End();++it)
-   {
-     UpdateMap(it.GetMeasurementVector(),newBeta,newSize);
-   }
+	// Compute the new learning coefficient
+	double newBeta = m_BetaFunctor( 
+						currentIteration, m_NumberOfIterations, m_BetaInit, m_BetaEnd );
+
+	// Compute the new neighborhood size
+	SizeType newSize = m_NeighborhoodSizeFunctor( 
+						currentIteration, m_NumberOfIterations, m_NeighborhoodSizeInit );
+
+	// update the neurons map with each example of the training set.
+	otbMsgDebugMacro(<<"Beta: "<<newBeta<<", radius: "<<newSize);
+	for ( typename ListSampleType::Iterator it = m_ListSample->Begin();
+			it != m_ListSample->End(); 
+			++it )
+	{
+		UpdateMap( it.GetMeasurementVector(), newBeta, newSize );
+	}
+}
+/**
+ *	Output information redefinition
+ */
+template < class TListSample, class TMap,
+	class TSOMLearningBehaviorFunctor,
+	class TSOMNeighborhoodBehaviorFunctor >
+void
+SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor>
+::GenerateOutputInformation ()
+{
+	Superclass::GenerateOutputInformation();
+	this->GetOutput()->SetNumberOfComponentsPerPixel(
+		m_ListSample->GetMeasurementVectorSize() );
+
+	IndexType index;
+	index.Fill(0);
+
+	RegionType region;
+	region.SetIndex(index);
+	region.SetSize( this->GetMapSize() );
+	this->GetOutput()->SetRegions( region );
+
 }
+/**
+ *	Output redefinition
+ */
+template < class TListSample, class TMap,
+	class TSOMLearningBehaviorFunctor,
+	class TSOMNeighborhoodBehaviorFunctor >
+void
+SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor>
+::AllocateOutputs()
+{
+	if ( this->GetNumberOfOutputs() != 1 )
+		itkExceptionMacro( << "Number of output image should be 1" );
+	
+	// output neuron map fill
+	MapPointerType map = this->GetOutput(0);
+	map->Allocate();
+} 
+
 /** 
  * Main computation method 
  */
-template <class TListSample,class TMap>  
+template < class TListSample, class TMap,
+	class TSOMLearningBehaviorFunctor,
+	class TSOMNeighborhoodBehaviorFunctor >
 void
-SOM<TListSample,TMap>
+SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor>
 ::GenerateData(void)
 {
-  // output neuron map fill
-  MapPointerType map = this->GetOutput();
-  RegionType region;
-  IndexType index;
-  index.Fill(0);
-  region.SetIndex(index);
-  region.SetSize(m_MapSize);
-  map->SetRegions(region);
-  map->Allocate();
-  
-  if(m_RandomInit)
-    {
-      typedef itk::Statistics::MersenneTwisterRandomVariateGenerator GeneratorType;
-      typedef itk::ImageRegionIterator<MapType> IteratorType;
-      GeneratorType::Pointer generator = GeneratorType::New();
-      generator->Initialize(m_Seed);
-      NeuronType neuronInit;
-      IteratorType it(map,map->GetLargestPossibleRegion());
-      
-      for(it.GoToBegin();!it.IsAtEnd();++it)
+	this->AllocateOutputs();
+	this->BeforeThreadedGenerateData();
+
+	MapPointerType map = this->GetOutput(0);
+
+	if ( m_RandomInit )
 	{
-	  for(int i=0;i<NeuronType::Length;++i)
-	    {
-	      neuronInit[i]=static_cast<typename NeuronType::ValueType>(
-	        generator->GetUniformVariate(static_cast<double>(m_MinWeight),static_cast<double>(m_MaxWeight)));
-	    }
-	  it.Set(neuronInit);
+		typedef itk::Statistics::MersenneTwisterRandomVariateGenerator GeneratorType;
+		typedef itk::ImageRegionIterator<MapType> IteratorType;
+		GeneratorType::Pointer generator = GeneratorType::New();
+		generator->Initialize(m_Seed);
+
+		NeuronType neuronInit ( m_ListSample->GetMeasurementVectorSize() );
+		IteratorType it ( map, map->GetLargestPossibleRegion() );
+
+		for ( it.GoToBegin(); !it.IsAtEnd(); ++it )
+		{
+			for(unsigned int i=0;i< neuronInit.Size();++i)
+			{
+				neuronInit[i]=static_cast<typename NeuronType::ValueType>(
+								generator->GetUniformVariate(static_cast<double>(m_MinWeight),
+															static_cast<double>(m_MaxWeight)) );
+			}
+			it.Set(neuronInit);
+		}
+	}  
+	else
+	{
+		NeuronType neuronInit ( m_ListSample->GetMeasurementVectorSize() );
+		neuronInit.Fill(m_MaxWeight);
+		map->FillBuffer(neuronInit);
+	}
+
+	// Step through the iterations
+	for(unsigned int i = 0;i<m_NumberOfIterations;++i)
+	{
+		//otbMsgDebugMacro(<<"Step "<<i+1<<" / "<<m_NumberOfIterations);
+		std::cerr << "Step "<< i+1 <<" / "<<m_NumberOfIterations << "                         \r";
+		Step(i);
 	}
-    }  
-  else
-    {
-      NeuronType neuronInit;
-      neuronInit.Fill(m_MaxWeight);
-      map->FillBuffer(neuronInit);
-    }
-  
-  // Step through the iterations
-  for(unsigned int i = 0;i<m_NumberOfIterations;++i)
-    {
-      otbMsgDebugMacro(<<"Step "<<i+1<<" / "<<m_NumberOfIterations);
-      Step(i);
-    }
+
+	this->AfterThreadedGenerateData();
 }
 /** 
  *PrintSelf method 
  */
-template <class TListSample,class TMap>  
+template < class TListSample, class TMap,
+	class TSOMLearningBehaviorFunctor,
+	class TSOMNeighborhoodBehaviorFunctor >
 void 
-SOM<TListSample,TMap>
+SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor>
 ::PrintSelf(std::ostream& os, itk::Indent indent) const
 {
-  Superclass::PrintSelf(os,indent);
+	Superclass::PrintSelf(os,indent);
 }
+
 } // end namespace otb
+
 #endif
+
diff --git a/Code/Learning/otbSOMLearningBehaviorFunctor.h b/Code/Learning/otbSOMLearningBehaviorFunctor.h
new file mode 100644
index 0000000000000000000000000000000000000000..17e707384747614f8e5f097e895226b2fb8187aa
--- /dev/null
+++ b/Code/Learning/otbSOMLearningBehaviorFunctor.h
@@ -0,0 +1,67 @@
+/*=========================================================================
+
+Program:   ORFEO Toolbox
+Language:  C++
+Date:      $Date$
+Version:   $Revision$
+
+
+Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+See OTBCopyright.txt for details.
+
+Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. 
+See ITCopyright.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.
+
+=========================================================================*/
+
+#ifndef __otbSOMLearningBehaviorFunctor_h
+#define __otbSOMLearningBehaviorFunctor_h
+
+
+namespace otb {
+
+namespace Functor {
+
+	/** \class SOMLearningBehaviorFunctor
+	* \brief Classical Beta behavior over SOM training phase
+	*
+	*	This class implements an standart evolution of the $\beta$ weightening
+	*	coefficient over the SOM training. 
+	*
+	*	\f{equation*}
+		\beta = \beta_0 + \left( \beta_{\text{end}} - \beta_0 \right)
+			\frac{t}{t_{\text{end}}}
+		\f{equation*} 
+	*
+	*	\sa SOM
+	*/
+	class SOMLearningBehaviorFunctor
+	{
+		public :
+			/** Empty constructor / descructor */
+			CzihoSOMLearningBehaviorFunctor () { }
+			virtual ~CzihoSOMLearningBehaviorFunctor() { }
+
+			/** Functor */
+			virtual double operator() ( unsigned int currentIteration, 
+										unsigned int numberOfIterations,
+										double betaInit, double betaEnd )
+			{
+				return betaInit + ( betaEnd - betaInit )
+							* static_cast<double>( currentIteration )
+							/ static_cast<double>(  numberOfIterations );
+			}
+
+	}; // end of class SOMLearningBehaviorFunctor
+
+} // end namespace Functor
+
+} // end namespace otb
+
+#endif
+
+					
diff --git a/Code/Learning/otbSOMMap.h b/Code/Learning/otbSOMMap.h
index 173f9c26ed6bfcd7e150273de767c29c9a1742d8..a826d8e7b73d28b35a2c468e27ed68bda11b14d2 100644
--- a/Code/Learning/otbSOMMap.h
+++ b/Code/Learning/otbSOMMap.h
@@ -9,6 +9,9 @@ Version:   $Revision$
 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.
 
+Copyright (c) Institut Telecom ; Telecom Bretagne. All right reserved.
+See GETCopyright.txt for details.
+
 
 This software is distributed WITHOUT ANY WARRANTY; without even 
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
@@ -18,9 +21,9 @@ PURPOSE.  See the above copyright notices for more information.
 #ifndef _otbSOMMap_h
 #define _otbSOMMap_h
 
-#include "itkFixedArray.h"
+#include "itkVariableLengthVector.h"
 #include "itkEuclideanDistance.h"
-#include "otbImage.h"
+#include "otbVectorImage.h"
 
 namespace otb
 {
@@ -42,22 +45,26 @@ namespace otb
  * \sa SOM
  * \sa SOMActivationBuilder
  */
-template <class TNeuron=itk::FixedArray<float,3>, 
-          class TDistance=itk::Statistics::EuclideanDistance<TNeuron>,unsigned int VMapDimension=2>  
+template <class TNeuron=itk::VariableLengthVector<double>, 
+          class TDistance=itk::Statistics::EuclideanDistance<TNeuron>,
+		  unsigned int VMapDimension=2>  
 class ITK_EXPORT SOMMap  
-: public Image<TNeuron,VMapDimension>
+: public otb::VectorImage<typename TNeuron::ComponentType,VMapDimension>
 {
   public:
   /** Standard typedefs */
   typedef SOMMap  Self;
-  typedef Image<TNeuron,VMapDimension>  Superclass;
+  typedef otb::VectorImage<typename TNeuron::ComponentType,VMapDimension>  Superclass;
   typedef itk::SmartPointer<Self>       Pointer;
   typedef itk::SmartPointer<const Self> ConstPointer;
   
   /** Creation through object factory macro */
   itkNewMacro(Self);
-  /** Runtime informations macro */
-  itkTypeMacro(SOMMap,Image);
+  /** 
+   * There is no runtime informations macro since
+   * this class has to be considered to as a simple VectorImage 
+   * // itkTypeMacro(SOMMap,VectorImage);
+   * */
   
   /** Template parameters related typedefs */
   typedef TNeuron NeuronType;
diff --git a/Code/Learning/otbSOMMap.txx b/Code/Learning/otbSOMMap.txx
index 288a5ffee46004cecebf9aec05f903649e71ba97..a008f1f950d4f14fa1ecded7bcd90850dff3a556 100644
--- a/Code/Learning/otbSOMMap.txx
+++ b/Code/Learning/otbSOMMap.txx
@@ -9,6 +9,9 @@ Version:   $Revision$
 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.
 
+Copyright (c) Institut Telecom ; Telecom Bretagne. All right reserved.
+See GETCopyright.txt for details.
+
 
 This software is distributed WITHOUT ANY WARRANTY; without even 
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
@@ -59,6 +62,7 @@ SOMMap<TNeuron,TDistance,VMapDimension>
   
   // Define the minimum distance and position
   IndexType minPos = it.GetIndex();
+
   double minDistance = activation->Evaluate(sample,it.Get());
  
   // Iterate through the map to get the minimum distance position
diff --git a/Testing/Code/BasicFilters/CMakeLists.txt b/Testing/Code/BasicFilters/CMakeLists.txt
index f65f5025a244b8a538e3a162b28e4fd8d7037015..3a4cbb79ca10513b93a35bffa97657989813951a 100755
--- a/Testing/Code/BasicFilters/CMakeLists.txt
+++ b/Testing/Code/BasicFilters/CMakeLists.txt
@@ -774,6 +774,16 @@ ADD_TEST(bfTvRationalQuotientResampleImageFilter ${BASICFILTERS_TESTS7}
 		    80 80
 )
 
+# -------            otb::EuclideanDistanceWithMissingValue   ----------------------------
+
+  ADD_TEST(bfTuEuclideanDistanceWithMissingValueNew ${BASICFILTERS_TESTS8}
+         otbEuclideanDistanceWithMissingValueNew)
+
+ADD_TEST(bfTvEuclideanDistanceWithMissingValue ${BASICFILTERS_TESTS8}
+         otbEuclideanDistanceWithMissingValue)
+
+
+=======
 # -------            otb::LabelizeNeighborhoodConnectedImageFilter   ----------------------------
 
   ADD_TEST(bfTuLabelizeNeighborhoodConnectedImageFilterNew ${BASICFILTERS_TESTS8}
@@ -919,6 +929,8 @@ otbLabelizeNeighborhoodConnectedImageFilterNew.cxx
 otbLabelizeNeighborhoodConnectedImageFilter.cxx
 otbLabelizeConfidenceConnectedImageFilterNew.cxx
 otbLabelizeConfidenceConnectedImageFilter.cxx
+otbEuclideanDistanceWithMissingValueNew.cxx
+otbEuclideanDistanceWithMissingValue.cxx
 )
 
 INCLUDE_DIRECTORIES("${OTBTesting_BINARY_DIR}")
diff --git a/Testing/Code/BasicFilters/otbBasicFiltersTests8.cxx b/Testing/Code/BasicFilters/otbBasicFiltersTests8.cxx
index f4e4171f886963c1163f4c6272fa6da394b44da4..abf982d8af7ae06c53b5648f5e6cfcf5f319aeeb 100644
--- a/Testing/Code/BasicFilters/otbBasicFiltersTests8.cxx
+++ b/Testing/Code/BasicFilters/otbBasicFiltersTests8.cxx
@@ -33,4 +33,6 @@ void RegisterTests()
   REGISTER_TEST(otbLabelizeNeighborhoodConnectedImageFilter);
   REGISTER_TEST(otbLabelizeConfidenceConnectedImageFilterNew);
   REGISTER_TEST(otbLabelizeConfidenceConnectedImageFilter);
+  REGISTER_TEST(otbEuclideanDistanceWithMissingValueNew);
+  REGISTER_TEST(otbEuclideanDistanceWithMissingValue);
 }
diff --git a/Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.cxx b/Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b88fdfa4a3e5c5e7826ad4d7e38d2f93d938e7b0
--- /dev/null
+++ b/Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.cxx
@@ -0,0 +1,61 @@
+/*=========================================================================
+
+Program:   ORFEO Toolbox
+Language:  C++
+Date:      $Date$
+Version:   $Revision$
+
+
+Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+See OTBCopyright.txt for details.
+
+Copyright (c) Institut Telecom ; Telecom Bretagne. All rights reserved. 
+See ITCopyright.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.
+
+=========================================================================*/
+
+
+#include <iostream>
+
+#include "itkVariableLengthVector.h"
+#include "otbEuclideanDistanceWithMissingValue.h"
+
+int otbEuclideanDistanceWithMissingValue( int argc, char * argv[] )
+{
+
+  typedef itk::VariableLengthVector< double > VectorType;
+  typedef otb::Statistics::EuclideanDistanceWithMissingValue< VectorType > DistanceType;
+
+  DistanceType::Pointer dist = DistanceType::New();
+		
+  if ( dist->IsMissingValue( 0.0 ) )
+    return EXIT_FAILURE;
+
+  if ( dist->IsMissingValue( 1.0 ) )
+    return EXIT_FAILURE;
+
+  if ( dist->IsMissingValue( -1.0 ) )
+    return EXIT_FAILURE;
+
+  /*
+    std::cerr << "Is O Nan ?? -> " << dist->IsMissingValue( 0.0 ) << "\n";
+    std::cerr << "Is 1 Nan ?? -> " << dist->IsMissingValue( 1.0 ) << "\n";
+    std::cerr << "Is -1 Nan ?? -> " << dist->IsMissingValue( -1.0 ) << "\n";
+  */
+
+  double x = 0.0;
+
+  dist->SetToMissingValue(x);
+  if ( !dist->IsMissingValue( x ) )
+    return EXIT_FAILURE;
+  // std::cerr << "Is x (=" << x << ") Nan ?? -> " << dist->IsMissingValue( x ) << "\n";
+
+  return EXIT_SUCCESS;
+}
+
+
+
diff --git a/Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValueNew.cxx b/Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValueNew.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..063cdccfc3f15b10d076a84d273cdbbedd22e4bc
--- /dev/null
+++ b/Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValueNew.cxx
@@ -0,0 +1,39 @@
+/*=========================================================================
+
+Program:   ORFEO Toolbox
+Language:  C++
+Date:      $Date$
+Version:   $Revision$
+
+
+Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+See OTBCopyright.txt for details.
+
+Copyright (c) Institut Telecom ; Telecom Bretagne. All rights reserved. 
+See ITCopyright.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.
+
+=========================================================================*/
+
+
+#include <iostream>
+
+#include "itkVariableLengthVector.h"
+#include "otbEuclideanDistanceWithMissingValue.h"
+
+int otbEuclideanDistanceWithMissingValueNew( int argc, char * argv[] )
+{
+
+  typedef itk::VariableLengthVector< double > VectorType;
+  typedef otb::Statistics::EuclideanDistanceWithMissingValue< VectorType > DistanceType;
+
+  DistanceType::Pointer dist = DistanceType::New();
+
+  return EXIT_SUCCESS;
+}
+
+
+
diff --git a/Testing/Code/Learning/CMakeLists.txt b/Testing/Code/Learning/CMakeLists.txt
index 05aff8bbc77310d709c49c19f9fd326def92644b..1730b073844b4c8b36c15b41d6bdee91f388eb01 100644
--- a/Testing/Code/Learning/CMakeLists.txt
+++ b/Testing/Code/Learning/CMakeLists.txt
@@ -161,6 +161,20 @@ ADD_TEST(leTvSOM ${LEARNING_TESTS2}
 	${TEMP}/leSOMPoupeesSubOutputMap1.hdr
 	32 32 10 10 5 1.0 0.1 0)
 
+# -------            otb::PeriodicSOM   -----------------------------	
+
+ADD_TEST(leTuPeriodicSOMNew ${LEARNING_TESTS2}  
+        otbPeriodicSOMNew)
+
+ADD_TEST(leTvPeriodicSOM ${LEARNING_TESTS2}  
+        --compare-image ${EPSILON}
+	${BASELINE}/lePeriodicSOMPoupeesSubOutputMap1.hdr
+	${TEMP}/lePeriodicSOMPoupeesSubOutputMap1.hdr
+	otbSOM
+	${INPUTDATA}/poupees_sub.png
+	${TEMP}/lePeriodicSOMPoupeesSubOutputMap1.hdr
+	32 32 10 10 5 1.0 0.1 0)
+
 # -------            otb::SOMActivationBuilder   -----------------------------	
 
 ADD_TEST(leTuSOMActivationBuilderNew ${LEARNING_TESTS2}  
@@ -267,6 +281,8 @@ otbSOMMapNew.cxx
 otbSOMMap.cxx
 otbSOMNew.cxx
 otbSOM.cxx
+otbPeriodicSOMNew.cxx
+otbPeriodicSOM.cxx
 otbSOMActivationBuilderNew.cxx
 otbSOMActivationBuilder.cxx
 )
diff --git a/Testing/Code/Learning/otbLearningTests2.cxx b/Testing/Code/Learning/otbLearningTests2.cxx
index d7c0956f3447913311263a4013135a0dcd72f1b9..cc1f0e7232c6f33a054a1b59fa9f47c89bf9dfe6 100644
--- a/Testing/Code/Learning/otbLearningTests2.cxx
+++ b/Testing/Code/Learning/otbLearningTests2.cxx
@@ -37,6 +37,8 @@ REGISTER_TEST(otbSOMMapNew);
 REGISTER_TEST(otbSOMMap);
 REGISTER_TEST(otbSOMNew);
 REGISTER_TEST(otbSOM);
+REGISTER_TEST(otbPeriodicSOMNew);
+REGISTER_TEST(otbPeriodicSOM);
 REGISTER_TEST(otbSOMActivationBuilderNew);
 REGISTER_TEST(otbSOMActivationBuilder);
 }
diff --git a/Testing/Code/Learning/otbPeriodicSOM.cxx b/Testing/Code/Learning/otbPeriodicSOM.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..05b8a2c83632ef8ff2c29d0b157feef92a1a8543
--- /dev/null
+++ b/Testing/Code/Learning/otbPeriodicSOM.cxx
@@ -0,0 +1,109 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+#include "itkExceptionObject.h"
+#include "otbVectorImage.h"
+#include "otbSOMMap.h"
+#include "otbPeriodicSOM.h"
+#include "itkRGBPixel.h"
+#include "itkEuclideanDistance.h"
+#include "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+#include "itkListSample.h"
+#include "itkImageRegionIterator.h"
+
+int otbPeriodicSOM(int argc, char* argv[])
+{
+try
+  {
+    const unsigned int Dimension = 2;
+    char * inputFileName = argv[1];
+    char * outputFileName = argv[2];
+    unsigned int sizeX = atoi(argv[3]);
+    unsigned int sizeY = atoi(argv[4]);
+    unsigned int neighInitX = atoi(argv[5]);
+    unsigned int neighInitY= atoi(argv[6]);
+    unsigned int nbIterations= atoi(argv[7]);
+    double betaInit = atof(argv[8]);
+    double betaEnd= atof(argv[9]);
+    double initValue = atof(argv[10]);
+    
+
+    typedef double ComponentType;
+    typedef itk::VariableLengthVector<ComponentType> PixelType;
+    typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType;
+    typedef otb::SOMMap<PixelType,DistanceType,Dimension> MapType;
+    typedef otb::VectorImage<ComponentType,Dimension> ImageType;
+    typedef otb::ImageFileReader<ImageType> ReaderType;
+    typedef itk::Statistics::ListSample<PixelType>  ListSampleType;
+    
+    typedef otb::PeriodicSOM<ListSampleType,MapType> SOMType;
+    typedef otb::ImageFileWriter<MapType> WriterType;
+
+    ReaderType::Pointer reader = ReaderType::New();
+    reader->SetFileName(inputFileName);
+    reader->Update();
+
+    ListSampleType::Pointer listSample = ListSampleType::New();
+
+    itk::ImageRegionIterator<ImageType> it(reader->GetOutput(),reader->GetOutput()->GetLargestPossibleRegion());
+    
+    it.GoToBegin();
+    
+    while(!it.IsAtEnd())
+      {
+	listSample->PushBack(it.Get());
+	++it;
+      }
+
+    std::cout<<"LIST SAMPLE SIZE: "<<listSample->GetMeasurementVectorSize()<<std::endl;
+       
+    // Instantiation
+    SOMType::Pointer som = SOMType::New();
+    som->SetListSample(listSample);
+    SOMType::SizeType size;
+    size[0]=sizeX;
+    size[1]=sizeY;
+    som->SetMapSize(size);
+    SOMType::SizeType radius;
+    radius[0] = neighInitX;
+    radius[1] = neighInitY;
+    som->SetNeighborhoodSizeInit(radius);
+    som->SetNumberOfIterations(nbIterations);
+    som->SetBetaInit(betaInit);
+    som->SetBetaEnd(betaEnd);
+    som->SetMaxWeight(initValue);
+    som->SetRandomInit(false);
+
+    WriterType::Pointer writer = WriterType::New();
+    writer->SetFileName(outputFileName);
+    writer->SetInput(som->GetOutput());
+    writer->Update();
+  }
+catch( itk::ExceptionObject & err ) 
+  { 
+    std::cout << "Exception itk::ExceptionObject thrown !" << std::endl; 
+    std::cout << err << std::endl; 
+    return EXIT_FAILURE;
+  } 
+catch( ... ) 
+  { 
+    std::cout << "Unknown exception thrown !" << std::endl; 
+    return EXIT_FAILURE;
+  } 
+ return EXIT_SUCCESS;
+}
diff --git a/Testing/Code/Learning/otbPeriodicSOMNew.cxx b/Testing/Code/Learning/otbPeriodicSOMNew.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3f8d35e9e2765a272db3845c99b1fc86720a8c5b
--- /dev/null
+++ b/Testing/Code/Learning/otbPeriodicSOMNew.cxx
@@ -0,0 +1,53 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+#include "itkExceptionObject.h"
+#include "otbSOMMap.h"
+#include "otbPeriodicSOM.h"
+#include "itkRGBPixel.h"
+#include "itkEuclideanDistance.h"
+#include "itkListSample.h"
+
+int otbPeriodicSOMNew(int argc, char* argv[])
+{
+try
+  {
+    const unsigned int Dimension = 2;
+    typedef float ComponentType;
+    typedef itk::VariableLengthVector<ComponentType> PixelType;
+    typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType;
+    typedef otb::SOMMap<PixelType,DistanceType,Dimension> SOMMapType;
+//     typedef itk::Statistics::ImageToListAdaptor<SOMMapType> AdaptorType;
+    typedef itk::Statistics::ListSample<PixelType> ListSampleType;
+    typedef otb::PeriodicSOM<ListSampleType,SOMMapType> SOMType;
+
+    // Instantiation
+    SOMType::Pointer som = SOMType::New();
+  }
+catch( itk::ExceptionObject & err ) 
+  { 
+    std::cout << "Exception itk::ExceptionObject thrown !" << std::endl; 
+    std::cout << err << std::endl; 
+    return EXIT_FAILURE;
+  } 
+catch( ... ) 
+  { 
+    std::cout << "Unknown exception thrown !" << std::endl; 
+    return EXIT_FAILURE;
+  } 
+ return EXIT_SUCCESS;
+}
diff --git a/Testing/Code/Learning/otbSOM.cxx b/Testing/Code/Learning/otbSOM.cxx
index 71367c1d4f25f59f3f7d9880e53aaab5d2046177..03b1474f394618e49f21de83120af108de41e6e2 100644
--- a/Testing/Code/Learning/otbSOM.cxx
+++ b/Testing/Code/Learning/otbSOM.cxx
@@ -16,14 +16,15 @@
 
 =========================================================================*/
 #include "itkExceptionObject.h"
-#include "otbImage.h"
+#include "otbVectorImage.h"
 #include "otbSOMMap.h"
 #include "otbSOM.h"
 #include "itkRGBPixel.h"
 #include "itkEuclideanDistance.h"
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
-#include "itkImageToListAdaptor.h"
+#include "itkListSample.h"
+#include "itkImageRegionIterator.h"
 
 int otbSOM(int argc, char* argv[])
 {
@@ -43,26 +44,37 @@ try
     
 
     typedef double ComponentType;
-    typedef itk::RGBPixel<ComponentType> PixelType;
+    typedef itk::VariableLengthVector<ComponentType> PixelType;
     typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType;
     typedef otb::SOMMap<PixelType,DistanceType,Dimension> MapType;
-    typedef otb::Image<PixelType,Dimension> ImageType;
+    typedef otb::VectorImage<ComponentType,Dimension> ImageType;
     typedef otb::ImageFileReader<ImageType> ReaderType;
-    typedef itk::Statistics::ImageToListAdaptor<ImageType> ListAdaptorType;
+    typedef itk::Statistics::ListSample<PixelType>  ListSampleType;
     
-    typedef otb::SOM<ListAdaptorType,MapType> SOMType;
+    typedef otb::SOM<ListSampleType,MapType> SOMType;
     typedef otb::ImageFileWriter<MapType> WriterType;
 
     ReaderType::Pointer reader = ReaderType::New();
     reader->SetFileName(inputFileName);
     reader->Update();
 
-    ListAdaptorType::Pointer adaptor = ListAdaptorType::New();
-    adaptor->SetImage(reader->GetOutput());
+    ListSampleType::Pointer listSample = ListSampleType::New();
+
+    itk::ImageRegionIterator<ImageType> it(reader->GetOutput(),reader->GetOutput()->GetLargestPossibleRegion());
+    
+    it.GoToBegin();
     
+    while(!it.IsAtEnd())
+      {
+	listSample->PushBack(it.Get());
+	++it;
+      }
+
+    std::cout<<"LIST SAMPLE SIZE: "<<listSample->GetMeasurementVectorSize()<<std::endl;
+       
     // Instantiation
     SOMType::Pointer som = SOMType::New();
-    som->SetListSample(adaptor);
+    som->SetListSample(listSample);
     SOMType::SizeType size;
     size[0]=sizeX;
     size[1]=sizeY;
diff --git a/Testing/Code/Learning/otbSOMActivationBuilder.cxx b/Testing/Code/Learning/otbSOMActivationBuilder.cxx
index c3a6494858b5aaff8e50044a9a18a8e2a1863838..7eb60a3e41460cd90653f3aa3a88e4cc6ec9dcf0 100644
--- a/Testing/Code/Learning/otbSOMActivationBuilder.cxx
+++ b/Testing/Code/Learning/otbSOMActivationBuilder.cxx
@@ -19,11 +19,13 @@
 #include "otbImage.h"
 #include "otbSOMMap.h"
 #include "otbSOMActivationBuilder.h"
-#include "itkRGBPixel.h"
+#include "itkVariableLengthVector.h"
 #include "itkEuclideanDistance.h"
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
-#include "itkImageToListAdaptor.h"
+#include "itkListSample.h"
+#include "otbVectorImage.h"
+#include "itkImageRegionIterator.h"
 
 int otbSOMActivationBuilder(int argc, char* argv[])
 {
@@ -36,33 +38,43 @@ try
   
     typedef float ComponentType;
     typedef unsigned char OutputPixelType;
-    typedef itk::RGBPixel<ComponentType> PixelType;
+    typedef itk::VariableLengthVector<ComponentType> PixelType;
     typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType;
 
     typedef otb::SOMMap<PixelType,DistanceType,Dimension> MapType;
     typedef otb::ImageFileReader<MapType> MapReaderType;
 
-    typedef otb::Image<PixelType,Dimension> InputImageType;
+    typedef otb::VectorImage<ComponentType,Dimension> InputImageType;
     typedef otb::ImageFileReader<InputImageType> ReaderType;
-    typedef itk::Statistics::ImageToListAdaptor<InputImageType> AdaptorType;
+    typedef itk::Statistics::ListSample<PixelType> ListSampleType;
 
     typedef otb::Image<OutputPixelType,Dimension> OutputImageType;
     typedef otb::ImageFileWriter<OutputImageType> WriterType;
 
-    typedef otb::SOMActivationBuilder<AdaptorType,MapType,OutputImageType> SOMActivationBuilderType;
+    typedef otb::SOMActivationBuilder<ListSampleType,MapType,OutputImageType> SOMActivationBuilderType;
 
     ReaderType::Pointer reader = ReaderType::New();
     reader->SetFileName(vectorSetFileName);    
     reader->Update();
-    AdaptorType::Pointer adaptor = AdaptorType::New();
-    adaptor->SetImage(reader->GetOutput());
+
+     ListSampleType::Pointer listSample = ListSampleType::New();
+
+    itk::ImageRegionIterator<InputImageType> it(reader->GetOutput(),reader->GetOutput()->GetLargestPossibleRegion());
+    
+    it.GoToBegin();
+    
+    while(!it.IsAtEnd())
+      {
+	listSample->PushBack(it.Get());
+	++it;
+      }
     
     MapReaderType::Pointer mapReader = MapReaderType::New();
     mapReader->SetFileName(mapFileName);
 
     SOMActivationBuilderType::Pointer somAct = SOMActivationBuilderType::New();
     somAct->SetInput(mapReader->GetOutput());
-    somAct->SetListSample(adaptor);
+    somAct->SetListSample(listSample);
 
     WriterType::Pointer writer = WriterType::New();
     writer->SetFileName(outputFileName);
diff --git a/Testing/Code/Learning/otbSOMActivationBuilderNew.cxx b/Testing/Code/Learning/otbSOMActivationBuilderNew.cxx
index 85d704ee54d4ea4317a3f9811e071552db32fe5c..1e75883dfe44a0d488a54300c68e9bad3b75e789 100644
--- a/Testing/Code/Learning/otbSOMActivationBuilderNew.cxx
+++ b/Testing/Code/Learning/otbSOMActivationBuilderNew.cxx
@@ -19,10 +19,11 @@
 #include "otbSOMMap.h"
 #include "otbSOM.h"
 #include "otbSOMActivationBuilder.h"
-#include "itkRGBPixel.h"
 #include "itkEuclideanDistance.h"
-#include "itkImageToListAdaptor.h"
-
+#include "itkListSample.h"
+#include "itkVariableLengthVector.h"
+#include "otbImage.h"
+#include "otbVectorImage.h"
 
 int otbSOMActivationBuilderNew(int argc, char* argv[])
 {
@@ -31,14 +32,14 @@ try
     const unsigned int Dimension =2;
     typedef float ComponentType;
     typedef unsigned char OutputPixelType;
-    typedef itk::RGBPixel<ComponentType> PixelType;
+    typedef itk::VariableLengthVector<ComponentType> PixelType;
     typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType;
 
     typedef otb::SOMMap<PixelType,DistanceType,Dimension> MapType;
-    typedef otb::Image<PixelType,Dimension> InputImageType;
-    typedef itk::Statistics::ImageToListAdaptor<InputImageType> AdaptorType;
+    typedef otb::VectorImage<ComponentType,Dimension> InputImageType;
+    typedef itk::Statistics::ListSample<PixelType> ListSampleType;
     typedef otb::Image<OutputPixelType,Dimension> OutputImageType;
-    typedef otb::SOMActivationBuilder<AdaptorType,MapType,OutputImageType> SOMActivationBuilderType;
+    typedef otb::SOMActivationBuilder<ListSampleType,MapType,OutputImageType> SOMActivationBuilderType;
 
     // Instantiation
     SOMActivationBuilderType::Pointer somAct = SOMActivationBuilderType::New();
diff --git a/Testing/Code/Learning/otbSOMClassifier.cxx b/Testing/Code/Learning/otbSOMClassifier.cxx
index 838d09cee1f8f7aa58144a8ad503bdd7f777785c..a7045c1012666cb1939e31d8648b881034b6e974 100644
--- a/Testing/Code/Learning/otbSOMClassifier.cxx
+++ b/Testing/Code/Learning/otbSOMClassifier.cxx
@@ -22,12 +22,13 @@
 
 #include <fstream>
 #include "otbVectorImage.h"
+#include "otbImage.h"
 #include "otbSOMMap.h"
 #include "otbSOMClassifier.h"
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
 #include "itkImageRegionIterator.h"
-#include "itkImageToListAdaptor.h"
+#include "itkListSample.h"
 
 int otbSOMClassifier(int argc, char* argv[] )
 {
@@ -48,13 +49,13 @@ int otbSOMClassifier(int argc, char* argv[] )
     typedef int                                 LabelPixelType;
     const   unsigned int        	         Dimension = 2;
 
-    typedef itk::RGBPixel<InputPixelType> PixelType;
+    typedef itk::VariableLengthVector<InputPixelType> PixelType;
     typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType;
     typedef otb::SOMMap<PixelType,DistanceType,Dimension> SOMMapType;
-    typedef otb::Image<PixelType,Dimension> InputImageType;
+    typedef otb::VectorImage<InputPixelType,Dimension> InputImageType;
     typedef otb::ImageFileReader< InputImageType  >  ReaderType;
     typedef otb::ImageFileReader<SOMMapType> SOMReaderType;
-    typedef itk::Statistics::ImageToListAdaptor< InputImageType > SampleType;
+    typedef itk::Statistics::ListSample< PixelType > SampleType;
     typedef otb::SOMClassifier<SampleType,SOMMapType,LabelPixelType> ClassifierType;
     typedef otb::Image<LabelPixelType, Dimension >  OutputImageType;
     typedef itk::ImageRegionIterator< OutputImageType>  OutputIteratorType;
@@ -70,11 +71,20 @@ int otbSOMClassifier(int argc, char* argv[] )
     somreader->Update();
     std::cout<<"SOM map read"<<std::endl;
 
-    SampleType::Pointer sample = SampleType::New();    
-    sample->SetImage(reader->GetOutput());
+    SampleType::Pointer listSample = SampleType::New();
+
+    itk::ImageRegionIterator<InputImageType> it(reader->GetOutput(),reader->GetOutput()->GetLargestPossibleRegion());
+    
+    it.GoToBegin();
+    
+    while(!it.IsAtEnd())
+      {
+	listSample->PushBack(it.Get());
+	++it;
+      }
 
     ClassifierType::Pointer classifier = ClassifierType::New() ;
-    classifier->SetSample(sample.GetPointer());
+    classifier->SetSample(listSample.GetPointer());
     classifier->SetMap(somreader->GetOutput());
     classifier->Update() ;
 
diff --git a/Testing/Code/Learning/otbSOMClassifierNew.cxx b/Testing/Code/Learning/otbSOMClassifierNew.cxx
index 0e53d63797945ee2408bb56f9834301fbbf48f59..ec95897e89ff4017f036e223a533bca2bc77d86d 100644
--- a/Testing/Code/Learning/otbSOMClassifierNew.cxx
+++ b/Testing/Code/Learning/otbSOMClassifierNew.cxx
@@ -23,7 +23,8 @@
 #include <fstream>
 #include "otbSOMMap.h"
 #include "otbSOMClassifier.h"
-#include "itkImageToListAdaptor.h"
+#include "itkListSample.h"
+#include "otbVectorImage.h"
 
 int otbSOMClassifierNew(int argc, char* argv[] )
 { 
@@ -33,11 +34,11 @@ int otbSOMClassifierNew(int argc, char* argv[] )
       typedef int                            LabelPixelType;
       const   unsigned int        	     Dimension = 2;
       
-      typedef itk::RGBPixel<InputPixelType> PixelType;
+      typedef itk::VariableLengthVector<InputPixelType> PixelType;
       typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType;
       typedef otb::SOMMap<PixelType,DistanceType,Dimension> SOMMapType;
-      typedef otb::Image<PixelType,Dimension> InputImageType;
-      typedef itk::Statistics::ImageToListAdaptor< InputImageType > SampleType;
+      typedef otb::VectorImage<InputPixelType,Dimension> InputImageType;
+      typedef itk::Statistics::ListSample< PixelType > SampleType;
       typedef otb::SOMClassifier<SampleType,SOMMapType,LabelPixelType> ClassifierType;    
       
       ClassifierType::Pointer classifier = ClassifierType::New() ;
diff --git a/Testing/Code/Learning/otbSOMMap.cxx b/Testing/Code/Learning/otbSOMMap.cxx
index 5fa01dcfde38ae6c135c4abf4b5c2376e6d7eb3c..f85fbe17ebff28d9db1b1e6e56dcb68d5ce726c3 100644
--- a/Testing/Code/Learning/otbSOMMap.cxx
+++ b/Testing/Code/Learning/otbSOMMap.cxx
@@ -19,17 +19,19 @@
 #include "otbSOMMap.h"
 #include "itkRGBPixel.h"
 #include "itkEuclideanDistance.h"
+#include "itkVariableLengthVector.h"
 
 int otbSOMMap(int argc, char* argv[])
 {
 try
   {
     const unsigned int Dimension = 2;
-    typedef float ComponentType;
-    typedef itk::RGBPixel<ComponentType> PixelType;
-    typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType;
+    typedef float InternalPixelType;
+    typedef itk::VariableLengthVector<InternalPixelType> PixelType;
+        typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType;
     typedef otb::SOMMap<PixelType,DistanceType,Dimension> SOMMapType;
 
+
     // Instantiation
     SOMMapType::Pointer somMap = SOMMapType::New();
 
@@ -42,15 +44,18 @@ try
     region.SetIndex(index);
     region.SetSize(size);
     somMap->SetRegions(region);
+    somMap->SetNumberOfComponentsPerPixel(3);
     somMap->Allocate();
     
     // Filling with null pixels
     PixelType nullPixel;
+    nullPixel.SetSize(3);
     nullPixel.Fill(0);
     somMap->FillBuffer(nullPixel);
 
     // Definition of a non-null pixel
     PixelType winner;
+    winner.SetSize(3);
     winner.Fill(1);
     index.Fill(32);
     somMap->SetPixel(index,winner);
diff --git a/Testing/Code/Learning/otbSOMNew.cxx b/Testing/Code/Learning/otbSOMNew.cxx
index 4a24a778a8834ecb6552767e8e4e818bbbcf9ccb..326ff6bd79ac9d1bac1b6ba2357e58374a8e4aa4 100644
--- a/Testing/Code/Learning/otbSOMNew.cxx
+++ b/Testing/Code/Learning/otbSOMNew.cxx
@@ -20,7 +20,7 @@
 #include "otbSOM.h"
 #include "itkRGBPixel.h"
 #include "itkEuclideanDistance.h"
-#include "itkImageToListAdaptor.h"
+#include "itkListSample.h"
 
 int otbSOMNew(int argc, char* argv[])
 {
@@ -28,11 +28,12 @@ try
   {
     const unsigned int Dimension = 2;
     typedef float ComponentType;
-    typedef itk::RGBPixel<ComponentType> PixelType;
+    typedef itk::VariableLengthVector<ComponentType> PixelType;
     typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType;
     typedef otb::SOMMap<PixelType,DistanceType,Dimension> SOMMapType;
-    typedef itk::Statistics::ImageToListAdaptor<SOMMapType> AdaptorType;
-    typedef otb::SOM<AdaptorType,SOMMapType> SOMType;
+//     typedef itk::Statistics::ImageToListAdaptor<SOMMapType> AdaptorType;
+    typedef itk::Statistics::ListSample<PixelType> ListSampleType;
+    typedef otb::SOM<ListSampleType,SOMMapType> SOMType;
 
     // Instantiation
     SOMType::Pointer som = SOMType::New();