diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx
index af319236f5f199b3018525dc440cdc6bef817d01..d714051526b91ca056376a667b0b4f8dfb1db80c 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx
@@ -93,6 +93,12 @@ OGRFieldType otb::ogr::FieldDefn::GetType() const
   return m_Definition->GetType();
 }
 
+
+std::ostream & otb::ogr::operator<<(std::ostream & os, otb::ogr::FieldDefn const& defn)
+{
+  return os << defn.GetName()
+    << " (" << OGRFieldDefn::GetFieldTypeName(defn.GetType()) << ")";
+}
 /*===========================================================================*/
 /*=================================[ Field ]=================================*/
 /*===========================================================================*/
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h
index 4fa1d6b38e389dca26dcdb7767a7091d94ca1355..c80bce4d7a8929f9fe873c37a353587d046c8f95 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h
@@ -47,6 +47,9 @@ public:
   std::string  GetName() const; //!< Field name accessor.
   OGRFieldType GetType() const; //!< Field type accessor.
 
+  OGRFieldDefn & ogr()       { return *m_Definition; }
+  OGRFieldDefn & ogr() const { return *m_Definition; }
+
 private:
   /**Pointer to the actual definition.
    * \internal pointer in order to support assignments
@@ -54,6 +57,14 @@ private:
   OGRFieldDefn * m_Definition;
   };
 
+inline
+bool operator==(FieldDefn const& lhs, FieldDefn const& rhs)
+  {
+  return lhs.GetName() == rhs.GetName()
+    &&   lhs.GetType() == rhs.GetType();
+  }
+
+std::ostream & operator<<(std::ostream & os, FieldDefn const& defn);
 
 /*===========================================================================*/
 /*=================================[ Field ]=================================*/
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx
index cda766e6fca56078f45eaf9983980fa996bc9b20..5b16a89cd934e6b806ba1ae035d8c8e1bea25d74 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx
@@ -117,6 +117,7 @@ template
 template
   < typename T
   , void ( OGRFeature::*ptr_to_function )(int, T value)
+  , typename ActualParamType = T
   > class MemberSetterPtr
     {
   public:
@@ -263,8 +264,8 @@ typedef map
   , pair<int_<OFTIntegerList>, MemberContainerSetterPtr<int,    &OGRFeature::SetField> >
   , pair<int_<OFTReal>,        MemberSetterPtr<double,          &OGRFeature::SetField> >
   , pair<int_<OFTRealList>,    MemberContainerSetterPtr<double, &OGRFeature::SetField> >
-  // , pair<int_<OFTString>,      MemberSetterPtr<char const*,     &OGRFeature::SetField, std::string> >
-  // , pair<int_<OFTStringList>,  MemberSetterPtr<char const*,     &OGRFeature::GetFieldAsString, std::string> >
+  // , pair<int_<OFTString>,      MemberSetterPtr<char const*,     &OGRFeature::SetField/*, std::string*/> >
+  // , pair<int_<OFTStringList>,  MemberContainerSetterPtr<char const*,     &OGRFeature::SetField, std::string> >
   > FieldSetters_Map;
 
 } // namespace internal
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx
index 84f232a6c2bc02ac820455fcbab5e2f0f70ab1b3..b40527010103c526648adbabca2fa2e00c228e4c 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx
@@ -219,10 +219,10 @@ OGRFeatureDefn & otb::ogr::Layer::GetLayerDefn() const
 }
 
 void otb::ogr::Layer::CreateField(
-  OGRFieldDefn const& field, bool bApproxOK/* = true */)
+  FieldDefn const& field, bool bApproxOK/* = true */)
 {
   assert(m_Layer && "OGRLayer not initialized");
-  const OGRErr res = m_Layer->CreateField(const_cast <OGRFieldDefn*>(&field), bApproxOK);
+  const OGRErr res = m_Layer->CreateField(&field.ogr(), bApproxOK);
   if (res != OGRERR_NONE)
     {
     itkGenericExceptionMacro(<< "Cannot create a field in the layer <"
@@ -247,7 +247,7 @@ void otb::ogr::Layer::DeleteField(size_t fieldIndex)
 }
 
 void otb::ogr::Layer::AlterFieldDefn(
-  size_t fieldIndex, OGRFieldDefn const& newFieldDefn, int nFlags)
+  size_t fieldIndex, FieldDefn const& newFieldDefn, int nFlags)
 {
   assert(m_Layer && "OGRLayer not initialized");
 #if GDAL_VERSION_NUM < 1900
@@ -256,7 +256,7 @@ void otb::ogr::Layer::AlterFieldDefn(
 #else
   const OGRErr res = m_Layer->AlterFieldDefn(
     int(fieldIndex),
-    const_cast <OGRFieldDefn*>(&newFieldDefn),
+    &newFieldDefn.ogr(),
     nFlags);
   if (res != OGRERR_NONE)
     {
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h
index 987fc2a9b541ccd43c11548828776e71da41fa6a..2245455018168e85db7c63376f46cfbe289568d9 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h
@@ -31,7 +31,6 @@ class OGRLayer;
 class OGRDataSource;
 class OGRGeometry;
 class OGRFeatureDefn;
-class OGRFieldDefn;
 
 namespace otb { namespace ogr {
 /**\ingroup gGeometry
@@ -366,7 +365,7 @@ public:
    * \sa \c OGRLayer::CreateField()
    * \todo Move to use \c otb::ogr::FieldDefn
    */
-  void CreateField(OGRFieldDefn const& field, bool bApproxOK = true);
+  void CreateField(FieldDefn const& field, bool bApproxOK = true);
 
   /**
    * Deletes a field.
@@ -398,7 +397,7 @@ public:
    * v1.9.0 at least.
    * \todo Move to use \c otb::ogr::FieldDefn
    */
-  void AlterFieldDefn(size_t fieldIndex, OGRFieldDefn const& newFieldDefn, int nFlags);
+  void AlterFieldDefn(size_t fieldIndex, FieldDefn const& newFieldDefn, int nFlags);
 
   /**
    * Moves a field from one position to another.
diff --git a/Testing/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapperNew.cxx b/Testing/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapperNew.cxx
index 21a27c1aa4cf1231543af6adfa8b2265348f3c41..1e584a0436668c0c0e2358635c325b3c8dceb97e 100644
--- a/Testing/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapperNew.cxx
+++ b/Testing/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapperNew.cxx
@@ -36,7 +36,27 @@ using namespace otb;
  */
 
 /*===========================================================================*/
-/*==============================[ other stuff ]==============================*/
+/*===============================[ Constants ]===============================*/
+/*===========================================================================*/
+const std::string k_one = "one";
+const std::string k_two = "two";
+
+/*const*/ OGRFieldDefn k_f0_("OFTInteger", OFTInteger);
+/*const*/ OGRFieldDefn k_f1_("OFTReal", OFTReal);
+/*const*/ OGRFieldDefn k_f2_("OFTString", OFTString);
+/*const*/ OGRFieldDefn k_f3_("OFTIntegerList", OFTIntegerList);
+/*const*/ OGRFieldDefn k_f4_("OFTRealList", OFTRealList);
+/*const*/ OGRFieldDefn k_f5_("OFTStringList", OFTStringList);
+
+ogr::FieldDefn k_f0(k_f0_);
+ogr::FieldDefn k_f1(k_f1_);
+ogr::FieldDefn k_f2(k_f2_);
+ogr::FieldDefn k_f3(k_f3_);
+ogr::FieldDefn k_f4(k_f4_);
+ogr::FieldDefn k_f5(k_f5_);
+
+/*===========================================================================*/
+/*==================================[ UTs ]==================================*/
 /*===========================================================================*/
 
 BOOST_AUTO_TEST_CASE(OGRDataSource_new_empty)
@@ -46,13 +66,9 @@ BOOST_AUTO_TEST_CASE(OGRDataSource_new_empty)
   BOOST_CHECK_EQUAL(ds->GetLayersCount(), 0);
   BOOST_CHECK_EQUAL(ds->Size(false), 0);
   BOOST_CHECK_EQUAL(ds->Size(true), 0);
-  BOOST_CHECK_EQUAL(ds->GetLayerChecked(0),otb::ogr::Layer(0));
   BOOST_CHECK_THROW(ds->GetLayerChecked(0), itk::ExceptionObject);
 }
 
-const std::string k_one = "one";
-const std::string k_two = "two";
-
 BOOST_AUTO_TEST_CASE(OGRDataSource_mem_add_n_del_layer)
 {
   ogr::DataSource::Pointer ds = ogr::DataSource::New();
@@ -127,3 +143,105 @@ BOOST_AUTO_TEST_CASE(OGRDataSource_new_shp)
   // BOOST_CHECK_THROW(ds -> CreateLayer(k_two), itk::ExceptionObject);
   // BOOST_CHECK_EQUAL(ds->GetLayersCount(), 1);
 }
+
+BOOST_AUTO_TEST_CASE(Add_n_Del_Fields)
+{
+  ogr::DataSource::Pointer ds = ogr::DataSource::New();
+  ogr::Layer l = ds -> CreateLayer(k_one);
+  ogr::Layer l0 = ds->GetLayerChecked(0);
+
+  OGRFeatureDefn & defn = l.GetLayerDefn();
+  BOOST_CHECK_EQUAL(defn.GetFieldCount(), 0);
+  l.CreateField(k_f0);
+  BOOST_CHECK_EQUAL(defn.GetFieldCount(), 1);
+  l.CreateField(k_f1);
+  BOOST_CHECK_EQUAL(defn.GetFieldCount(), 2);
+  l.CreateField(k_f2);
+  BOOST_CHECK_EQUAL(defn.GetFieldCount(), 3);
+  l.CreateField(k_f3);
+  BOOST_CHECK_EQUAL(defn.GetFieldCount(), 4);
+  l.CreateField(k_f4);
+  BOOST_CHECK_EQUAL(defn.GetFieldCount(), 5);
+  l.CreateField(k_f5);
+  BOOST_CHECK_EQUAL(defn.GetFieldCount(), 6);
+
+    {
+    ogr::FieldDefn f0(*defn.GetFieldDefn(0));
+    BOOST_CHECK_EQUAL(f0, k_f0);
+    ogr::FieldDefn f1(*defn.GetFieldDefn(1));
+    BOOST_CHECK_EQUAL(f1, k_f1);
+    ogr::FieldDefn f2(*defn.GetFieldDefn(2));
+    BOOST_CHECK_EQUAL(f2, k_f2);
+    ogr::FieldDefn f3(*defn.GetFieldDefn(3));
+    BOOST_CHECK_EQUAL(f3, k_f3);
+    ogr::FieldDefn f4(*defn.GetFieldDefn(4));
+    BOOST_CHECK_EQUAL(f4, k_f4);
+    ogr::FieldDefn f5(*defn.GetFieldDefn(5));
+    BOOST_CHECK_EQUAL(f5, k_f5);
+
+    BOOST_CHECK_EQUAL(defn.GetFieldDefn(6), (void*)0);
+    }
+
+  l.DeleteField(1);
+  BOOST_CHECK_EQUAL(defn.GetFieldCount(), 5);
+
+    {
+    ogr::FieldDefn f0(*defn.GetFieldDefn(0));
+    BOOST_CHECK_EQUAL(f0, k_f0);
+    ogr::FieldDefn f1(*defn.GetFieldDefn(1));
+    BOOST_CHECK_EQUAL(f1, k_f2);
+    ogr::FieldDefn f2(*defn.GetFieldDefn(2));
+    BOOST_CHECK_EQUAL(f2, k_f3);
+    ogr::FieldDefn f3(*defn.GetFieldDefn(3));
+    BOOST_CHECK_EQUAL(f3, k_f4);
+    ogr::FieldDefn f4(*defn.GetFieldDefn(4));
+    BOOST_CHECK_EQUAL(f4, k_f5);
+    }
+  // todo: add reoder tests
+}
+
+BOOST_AUTO_TEST_CASE(Add_n_Read_Fields)
+{
+  ogr::DataSource::Pointer ds = ogr::DataSource::New();
+  ogr::Layer l = ds -> CreateLayer(k_one);
+  ogr::Layer l0 = ds->GetLayerChecked(0);
+
+  OGRFeatureDefn & defn = l.GetLayerDefn();
+  l.CreateField(k_f0);
+  l.CreateField(k_f1);
+  l.CreateField(k_f2);
+  l.CreateField(k_f3);
+  l.CreateField(k_f4);
+  l.CreateField(k_f5);
+
+  ogr::Feature g0(defn);
+  const size_t NbFields = defn.GetFieldCount();
+  BOOST_CHECK_EQUAL(NbFields, g0.GetSize());
+  for (size_t i=0; i!=NbFields; ++i)
+    {
+    BOOST_ASSERT(!g0[i].HasBeenSet());
+    }
+
+  ogr::Field f0 = g0[0];
+  BOOST_CHECK_EQUAL(f0.GetName(), k_f0.GetName());
+  f0.SetValue(42);
+  BOOST_ASSERT(f0.HasBeenSet());
+  BOOST_CHECK_EQUAL(f0.GetValue<int>(), 42);
+  // BOOST_CHECK_assert_FAILS(f0.GetValue<double>(), itk::ExceptionObject);
+
+  ogr::Field f1 = g0["OFTReal"];
+  BOOST_CHECK_EQUAL(f1.GetName(), k_f1.GetName());
+  // f1.SetValue(42); // need to support types promotion
+  f1.SetValue(42.0); // need to support types promotion
+  BOOST_ASSERT(f1.HasBeenSet());
+  BOOST_CHECK_EQUAL(f1.GetValue<double>(), 42.0);
+
+#if 0 // not ready
+  ogr::Field f2 = g0["OFTString"];
+  BOOST_CHECK_EQUAL(f2.GetName(), k_f2.GetName());
+  f2.SetValue(("foobar")); // need to support types promotion
+  BOOST_ASSERT(f2.HasBeenSet());
+  BOOST_CHECK_EQUAL(f2.GetValue<std::string>(), "foobar");
+#endif
+
+}