diff --git a/Code/Common/otbJoinContainer.h b/Code/Common/otbJoinContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..fd315afa9d265cb03fc23fee7d467519417a2505
--- /dev/null
+++ b/Code/Common/otbJoinContainer.h
@@ -0,0 +1,64 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+#ifndef __otbJoinContainer_h
+#define __otbJoinContainer_h
+
+// #include <iosfwd>
+#include <string>
+
+#include <ostream>
+// #include <boost/range/iterator.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/empty.hpp>
+namespace otb
+{
+  /**\ingroup Common
+   * Joins elements from a range into a stream.
+   * \tparam TRange range type, see <a
+   * href="www.boost.org/doc/libs/release/libs/range/doc/html/">boost.Range</a>
+   * to see what qualifies as an \em Range.
+   * \param os  destination stream
+   * \param[in] range  Range to print
+   * \param[in] separator  Separator string to use between elements.
+   *
+   * \return the stream
+   * \throw None At least, this function is exception neutral.
+   */
+template <typename TRange> inline
+std::ostream & Join(std::ostream &os, TRange const& range, std::string const& separator)
+{
+  if (!boost::empty(range))
+    {
+    typename boost::range_iterator<TRange const>::type       first = boost::begin(range);
+    typename boost::range_iterator<TRange const>::type const last = boost::end(range);
+    os << *first;
+    for (++first; first!=last; ++first)
+      {
+      os << separator << *first;
+      }
+    }
+  return os;
+}
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+// #include "otbJoinContainer.txx"
+#endif
+
+#endif // __otbJoinContainer_h
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx
index 5216555995d54b16110b1fb3ea65e5a0c06b5e96..58e732092b3342a67d43ceab03523b77671bbdeb 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx
@@ -62,26 +62,16 @@ otb::ogr::Feature otb::ogr::Feature::clone() const
 void otb::ogr::Feature::PrintSelf(std::ostream & os, itk::Indent indent) const
 {
   CheckInvariants();
-  const itk::Indent one_indent = itk::Indent().GetNextIndent();
-  const int nbFields = m_Feature->GetFieldCount();
+  const size_t nbFields = m_Feature->GetFieldCount();
   os << indent << "+";
   os << " " << nbFields << " fields\n";
-  for (int i=0; i!=nbFields; ++i) {
+  indent = indent.GetNextIndent();
+  for (size_t i=0; i!=nbFields; ++i)
+    {
     assert(ogr().GetFieldDefnRef(i));
-    Field     field(*this, i);
-    os << indent << "|" << one_indent << "+ ";
-    os << field.GetName() << ": ";
-    switch (field.GetType())
-      {
-      case OFTInteger: os << field.GetValue<int>(); break;
-      case OFTReal   : os << field.GetValue<double>(); break;
-    case OFTString : os << field.GetValue<std::string>();
-      break;
-    default: os << "??? -> " << field.GetType(); break;
-      }
-    os << " (" << OGRFieldDefn::GetFieldTypeName(field.GetType()) << ")";
-    os << "\n";
-  }
+    Field const& field = (*this)[i];
+    field.PrintSelf(os, indent);
+    }
 }
 
 bool otb::ogr::operator==(otb::ogr::Feature const& lhs, otb::ogr::Feature const& rhs)
@@ -98,6 +88,20 @@ bool otb::ogr::operator==(otb::ogr::Feature const& lhs, otb::ogr::Feature const&
 ;
 }
 
+/*===========================================================================*/
+/*================================[ Fields ]=================================*/
+/*===========================================================================*/
 size_t otb::ogr::Feature::GetSize() const {
   return ogr().GetFieldCount();
 }
+
+otb::ogr::Field otb::ogr::Feature::operator[](size_t index)
+{
+    Field field(*this, index);
+    return field;
+}
+
+otb::ogr::Field const otb::ogr::Feature::operator[](size_t index) const
+{
+  return const_cast<Feature*>(this)->operator[](index);
+}
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h
index c959ee65b61702a37041ad5b43c6c7d3fa077d20..c07675c412d1f0d1e7298c63cc3bbb350ca30a72 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h
@@ -22,6 +22,7 @@
 #include <cassert>
 #include <boost/shared_ptr.hpp>
 #include "itkIndent.h"
+#include "otbOGRFieldWrapper.h"
 
 class OGRFeature;
 class OGRGeometry;
@@ -47,27 +48,22 @@ public:
   Feature clone() const;
   void PrintSelf(std::ostream &os, itk::Indent indent) const;
 
-  OGRFeature & ogr() const
-    { // not returning a OGRFeature const& because OGR is not const-correct
-    CheckInvariants();
-    return *m_Feature;
-    }
-  OGRFeature & ogr()
-    {
-    CheckInvariants();
-    return *m_Feature;
-    }
+  OGRFeature & ogr() const;
+  OGRFeature & ogr();
+  boost::shared_ptr<OGRFeature>      & sptr()       {return m_Feature; }
+  boost::shared_ptr<OGRFeature> const& sptr() const {return m_Feature; }
 
+  /**\name Fields */
+  //@{
   size_t GetSize() const;
+  Field       operator[](size_t index);
+  Field const operator[](size_t index) const;
+  //@}
 
   friend bool otb::ogr::operator==(Feature const& lhs, Feature const& rhs);
 private:
-  void CheckInvariants() const
-    {
-    assert(m_Feature && "OGRFeature can't be null");
-    }
+  void CheckInvariants() const;
   boost::shared_ptr<OGRFeature> m_Feature;
-
   };
 
 
@@ -76,7 +72,7 @@ private:
 
 
 #ifndef OTB_MANUAL_INSTANTIATION
-// #include "otbOGRFeatureWrapper.txx"
+#include "otbOGRFeatureWrapper.txx"
 #endif
 
 #endif // __otbOGRFeatureWrapper_h
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.txx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.txx
new file mode 100644
index 0000000000000000000000000000000000000000..a55995e8a30827dbefe2a8b22aaed3bdfd3ee9d2
--- /dev/null
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.txx
@@ -0,0 +1,48 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+#ifndef __otbOGRFeatureWrapper_txx
+#define __otbOGRFeatureWrapper_txx
+
+/*===========================================================================*/
+/*===============================[ Includes ]================================*/
+/*===========================================================================*/
+
+/*===========================================================================*/
+/*================================[ Feature ]================================*/
+/*===========================================================================*/
+inline
+OGRFeature & otb::ogr::Feature::ogr() const
+{ // not returning a OGRFeature const& because OGR is not const-correct
+  CheckInvariants();
+  return *m_Feature;
+}
+
+inline
+OGRFeature & otb::ogr::Feature::ogr()
+{
+  CheckInvariants();
+  return *m_Feature;
+}
+
+inline
+void otb::ogr::Feature::CheckInvariants() const
+{
+  assert(m_Feature && "OGRFeature can't be null");
+}
+
+#endif // __otbOGRFeatureWrapper_txx
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d5e66405d6093494d16ce464c5c3553c6a1e723b
--- /dev/null
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx
@@ -0,0 +1,132 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+
+/*===========================================================================*/
+/*===============================[ Includes ]================================*/
+/*===========================================================================*/
+#include "otbOGRFieldWrapper.h"
+#include <cassert>
+#include "ogr_feature.h"
+#include "otbOGRFeatureWrapper.h"
+#include "otbJoinContainer.h"
+
+/*===========================================================================*/
+/*===========================[ Static Assertions ]===========================*/
+/*===========================================================================*/
+namespace types_
+{
+BOOST_STATIC_ASSERT(!(boost::is_same<
+  MemberGetterPtr<int,         &OGRFeature::GetFieldAsInteger>,
+  MemberGetterPtr<double,      &OGRFeature::GetFieldAsDouble>
+  >::value
+  ));
+
+BOOST_STATIC_ASSERT(!(boost::is_same< int, float >::value));
+BOOST_STATIC_ASSERT(!(boost::is_same<
+    int_<OFTReal  >::type,
+    int_<OFTString>::type
+    >::value
+));
+BOOST_STATIC_ASSERT(!(boost::is_same<
+    at<FieldType_Map,  float>,
+    void_
+    >::value
+));
+BOOST_STATIC_ASSERT(!(boost::is_same<
+    at<FieldType_Map,  double>,
+    int_<OFTReal>
+    >::value
+));
+BOOST_STATIC_ASSERT(!(boost::is_same<
+    at<FieldType_Map,  double >::type,
+    at<FieldType_Map,  int >::type
+    >::value
+));
+BOOST_STATIC_ASSERT((
+    at<FieldType_Map,  double>::type::value !=
+    at<FieldType_Map,  int   >::type::value
+));
+BOOST_STATIC_ASSERT(!(boost::is_same<
+    at<FieldGetters_Map, int_<OFTReal> >,
+    at<FieldGetters_Map, int_<OFTString> >
+    >::value
+));
+}
+
+/*===========================================================================*/
+/*===============================[ FieldDefn ]===============================*/
+/*===========================================================================*/
+
+std::string otb::ogr::FieldDefn::GetName() const
+{
+  assert(m_definition);
+  return m_definition->GetNameRef();
+}
+
+OGRFieldType otb::ogr::FieldDefn::GetType() const
+{
+  assert(m_definition);
+  return m_definition->GetType();
+}
+
+/*===========================================================================*/
+/*=================================[ Field ]=================================*/
+/*===========================================================================*/
+
+otb::ogr::Field::Field(otb::ogr::Feature & feature, size_t index)
+: m_Definition(*feature.ogr().GetFieldDefnRef(index))
+, m_Feature(feature.sptr())
+, m_index(index)
+{
+  assert(m_Feature);
+  assert(m_Feature->GetFieldDefnRef(index));
+}
+
+std::ostream & otb::ogr::Field::PrintSelf(
+  std::ostream& os, itk::Indent indent) const
+{
+  const itk::Indent one_indent = itk::Indent().GetNextIndent();
+  // os << indent << "|" << one_indent << "+ ";
+  os << indent << this->GetName() << ": ";
+  switch (this->GetType())
+    {
+  case OFTInteger:
+    os << this->GetValue<int>();
+    break;
+  case OFTIntegerList:
+    os << '{';
+    otb::Join(os, this->GetValue<std::vector<int> >(), ", ") << '}';
+    break;
+  case OFTReal   :
+    os << this->GetValue<double>();
+    break;
+  case OFTRealList:
+    os << '{';
+    otb::Join(os, this->GetValue<std::vector<double> >(), ", ") << '}';
+    break;
+  case OFTString :
+    os << this->GetValue<std::string>();
+    break;
+  default:
+    os << "??? -> " << this->GetType();
+    break;
+    }
+  os << " (" << OGRFieldDefn::GetFieldTypeName(this->GetType()) << ")";
+  os << "\n";
+  return os;
+}
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h
index df05f05fdd88bcbf43478cd82446ed2c16506f1d..5d895b42c7114434491125e6576a1d2b56282fe3 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h
@@ -26,14 +26,18 @@
 #include <boost/mpl/int.hpp>
 #include <boost/mpl/at.hpp>
 
-#include <boost/mpl/assert.hpp>
+// #include <boost/mpl/assert.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/type_traits/is_same.hpp>
-// class OGRFeature;
-#include "ogr_feature.h"
+#include <boost/shared_ptr.hpp>
 class OGRFieldDefn;
+// class OGRFeature;
+#include "ogr_feature.h" // OGRFeature::*field_getters
+#include "ogr_core.h" // OGR enums
+#include "itkIndent.h"
+#include <cassert>
 
-
+#if 0
 #include <iomanip>
 template <typename RT, typename CT> void print_adress(RT (CT::*p)(int))
 {
@@ -47,9 +51,10 @@ template <typename RT, typename CT> void print_adress(RT (CT::*p)(int))
     }
   std::cout << "\n";
 }
+#endif
 
 
-namespace types_ { // Anonymous namespace
+namespace types_ { // namespace types_
 using namespace boost::mpl;
 typedef boost::mpl::map
   < pair<int, int_<OFTInteger> >
@@ -58,87 +63,65 @@ typedef boost::mpl::map
   , pair<std::vector<double>, int_<OFTRealList> >
   , pair<std::string, int_<OFTString> >
   , pair<std::vector<std::string>, int_<OFTStringList> >
+  // OFTBinary
+  // OFTDate
+  // OFTTime
+  // OFTDateTime
   > FieldType_Map;
 
 template
   < typename T
   , T ( OGRFeature::*ptr_to_function )(int)
   , typename FinalReturnType = T
-  > class member_function_get_ptr
+  > class MemberGetterPtr
     {
   public:
     static FinalReturnType call(OGRFeature &f, int index)
       {
-      // print_adress(ptr_to_function);
-      // print_adress(&OGRFeature::GetFieldAsString);
       return (f.*ptr_to_function)(index);
       }
     };
 
+template
+  < typename T
+  , T const* ( OGRFeature::*ptr_to_function )(int, int*)
+  , typename FinalReturnType = std::vector<T>
+  > class MemberContainerGetterPtr
+    {
+  public:
+    static FinalReturnType call(OGRFeature &f, int index)
+      {
+      int nb = 0;
+      T const* raw_container = (f.*ptr_to_function)(index, &nb);
+      FinalReturnType res(raw_container+0, raw_container+nb);
+      return res;
+      }
+    };
+
 typedef map
-  < pair<int_<OFTInteger>, member_function_get_ptr<int,         &OGRFeature::GetFieldAsInteger> >
-  , pair<int_<OFTReal>,    member_function_get_ptr<double,      &OGRFeature::GetFieldAsDouble> >
-  , pair<int_<OFTString>,  member_function_get_ptr<char const*, &OGRFeature::GetFieldAsString, std::string> >
+  < pair<int_<OFTInteger>,     MemberGetterPtr<int,             &OGRFeature::GetFieldAsInteger> >
+  , pair<int_<OFTIntegerList>, MemberContainerGetterPtr<int,    &OGRFeature::GetFieldAsIntegerList> >
+  , pair<int_<OFTReal>,        MemberGetterPtr<double,          &OGRFeature::GetFieldAsDouble> >
+  , pair<int_<OFTRealList>,    MemberContainerGetterPtr<double, &OGRFeature::GetFieldAsDoubleList> >
+  , pair<int_<OFTString>,      MemberGetterPtr<char const*,     &OGRFeature::GetFieldAsString, std::string> >
+  // , pair<int_<OFTStringList>,  MemberGetterPtr<char const*,     &OGRFeature::GetFieldAsString, std::string> >
   > FieldGetters_Map;
 
-BOOST_STATIC_ASSERT(!(boost::is_same<
-  member_function_get_ptr<int,         &OGRFeature::GetFieldAsInteger>,
-  member_function_get_ptr<double,      &OGRFeature::GetFieldAsDouble>
-  >::value
-  ));
-
-BOOST_STATIC_ASSERT(!(boost::is_same< int, float >::value));
-BOOST_STATIC_ASSERT(!(boost::is_same<
-  int_<OFTReal  >::type,
-  int_<OFTString>::type
-  >::value
-  ));
-BOOST_STATIC_ASSERT(!(boost::is_same<
-  at<FieldType_Map,  float>,
-  void_
-  >::value
-  ));
-BOOST_STATIC_ASSERT(!(boost::is_same<
-  at<FieldType_Map,  double>,
-  int_<OFTReal>
-  >::value
-  ));
-BOOST_STATIC_ASSERT(!(boost::is_same<
-  at<FieldType_Map,  double >::type,
-  at<FieldType_Map,  int >::type
-  >::value
-  ));
-BOOST_STATIC_ASSERT((
-  at<FieldType_Map,  double>::type::value !=
-  at<FieldType_Map,  int   >::type::value
-  ));
-BOOST_STATIC_ASSERT(!(boost::is_same<
-  at<FieldGetters_Map, int_<OFTReal> >,
-  at<FieldGetters_Map, int_<OFTString> >
-  >::value
-  ));
-} // Anonymous namespace
+} // namespace types_
 
 namespace otb { namespace ogr {
 class FieldDefn
   {
 public:
   FieldDefn(OGRFieldDefn& definition) : m_definition(&definition){ }
-  std::string  GetName() const
-    {
-    assert(m_definition);
-    return m_definition->GetNameRef();
-    }
-  OGRFieldType GetType() const
-    {
-    assert(m_definition);
-    return m_definition->GetType();
-    }
+  std::string  GetName() const;
+  OGRFieldType GetType() const;
 
 private:
   OGRFieldDefn * m_definition;
   };
 
+#if 0
 template <typename FieldType> struct FieldDecodingTraitsGetter {};
 template <typename FieldType> struct FieldDecodingTraits
   {
@@ -153,7 +136,7 @@ template <typename FieldType> struct FieldDecodingTraits
 template <> struct FieldDecodingTraitsGetter<int>
   {
   typedef int Type;
-  static Type Get(OGRFeature &f, int index)
+  static Type Get(OGRFeature &f, size_t index)
     {
     return f.GetFieldAsInteger(index);
     }
@@ -162,7 +145,7 @@ template <> struct FieldDecodingTraitsGetter<int>
 template <> struct FieldDecodingTraitsGetter<double>
   {
   typedef double Type;
-  static Type Get(OGRFeature &f, int index)
+  static Type Get(OGRFeature &f, size_t index)
     {
     return f.GetFieldAsDouble(index);
     }
@@ -171,25 +154,21 @@ template <> struct FieldDecodingTraitsGetter<double>
 template <> struct FieldDecodingTraitsGetter<std::string>
   {
   typedef std::string Type;
-  static Type Get(OGRFeature &f, int index)
+  static Type Get(OGRFeature &f, size_t index)
     {
     return f.GetFieldAsString(index);
     }
   };
+#endif
 
 /*===========================================================================*/
 /*=================================[ Field ]=================================*/
 /*===========================================================================*/
+class Feature;
 class Field
   {
 public:
-  Field(Feature const& feature, int index)
-    :   m_Definition(*feature.ogr().GetFieldDefnRef(index))
-      , m_Feature(feature)
-      , m_index(index)
-  {
-  assert(feature.ogr().GetFieldDefnRef(index));
-  }
+  Field(Feature & feature, size_t index);
   // Field(OGRFeature& field, FieldDefn const& definition);
   FieldDefn const& GetDefinition() const;
   OGRFieldType GetType() const
@@ -208,32 +187,19 @@ public:
     {
     const int VALUE = boost::mpl::at<types_::FieldType_Map, T>::type::value;
     typedef typename boost::mpl::at<types_::FieldType_Map, T>::type Kind;
-    BOOST_STATIC_ASSERT(!(boost::is_same< Kind, boost::mpl::void_ >::value));
+    BOOST_STATIC_ASSERT(!(boost::is_same<Kind, boost::mpl::void_>::value));
     assert(m_Definition.GetType() == Kind::value);
-    typedef typename boost::mpl::at< types_::FieldGetters_Map, Kind >::type function_;
-    BOOST_STATIC_ASSERT(!(boost::is_same< function_, boost::mpl::void_ >::value));
-    assert(m_index >= 0 && m_index < m_Feature.GetSize());
-    return function_::call(m_Feature.ogr(), m_index);
-    // return FieldDecodingTraitsGetter<T>::Get(m_Feature.ogr(), m_index);
+    typedef typename boost::mpl::at<types_::FieldGetters_Map, Kind>::type GetterType;
+    BOOST_STATIC_ASSERT(!(boost::is_same<GetterType, boost::mpl::void_>::value));
+    assert(m_index >= 0 && m_index < m_Feature->GetFieldCount());
+    return GetterType::call(*m_Feature, m_index);
     }
-#if 0
-  std::ostream & PrintSelf(std::ostream&os, itk::Indent indent) {
-    os << indent;
-    switch (GetType)
-      {
-machin_int:
-      os << GetValue<int>();
-      break;
-    default:
 
-      }
-    return os;
-  }
-#endif
+  std::ostream & PrintSelf(std::ostream&os, itk::Indent indent) const;
 private:
-  FieldDefn  m_Definition;
-  Feature    m_Feature;
-  int        m_index; // all the fields decoding is at the wrong place (OGRFeature instead of OGRField)
+  FieldDefn                       m_Definition;
+  boost::shared_ptr<OGRFeature> & m_Feature;
+  size_t                          m_index; // all the fields decoding is at the wrong place (OGRFeature instead of OGRField)
   };
 
 } } // end namespace otb::ogr