diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx
index 5f662404dd16fc76680ec3656e4daef7fe1fe0b8..bde1055472cafbee9c0587ae354784799500eaa7 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx
@@ -267,8 +267,7 @@ otb::ogr::Layer otb::ogr::DataSource::ExecuteSQL(
     return otb::ogr::Layer(0);
 #endif
     }
-  return otb::ogr::Layer(layer_ptr, m_DataSource);
-
+  return otb::ogr::Layer(layer_ptr, *m_DataSource);
 }
 
 
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h
index 0f5d26dd410c9d66d9c52568b70a34e21ce968f1..397140c38de68ea36896c379178d915214c4d818 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h
@@ -15,6 +15,7 @@
      PURPOSE.  See the above copyright notices for more information.
 
 =========================================================================*/
+
 #ifndef __otbOGRDataSourceWrapper_h
 #define __otbOGRDataSourceWrapper_h
 
@@ -191,7 +192,6 @@ public:
    */
   itkNewMacro(Self);
   itkTypeMacro(Layer, DataObject);
-  // itkStaticConstMacro(Dimension, unsigned int, VDimension);
   //@}
   /**\name Creation functions */
   //@{
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h
index 9ab8a5181b39e1e83b25583335aa28eaef3d169c..6b113fb444915c33fcdbacfcf246e10770f94618 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h
@@ -151,7 +151,7 @@ public:
   OGRFieldType GetType() const;
 
 private:
-  OGRFieldDefn * m_definition;
+  OGRFieldDefn * m_definition; // pointer in order to support assignments
   };
 
 #if 0
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx
index 9d2697c8ad582dd58e656d98f9ec809b9e10645c..8044d8a1ec7ef490f363e41649aa58905022d13a 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx
@@ -47,8 +47,8 @@ otb::ogr::Layer::Layer(OGRLayer* layer)
 {
 }
 
-otb::ogr::Layer::Layer(OGRLayer* layer, OGRDataSource* sourceInChargeOfLifeTime)
-: m_Layer(layer,  boost::bind(&OGRDataSource::ReleaseResultSet, sourceInChargeOfLifeTime, _1))
+otb::ogr::Layer::Layer(OGRLayer* layer, OGRDataSource& sourceInChargeOfLifeTime)
+: m_Layer(layer,  boost::bind(&OGRDataSource::ReleaseResultSet, boost::ref(sourceInChargeOfLifeTime), _1))
 {
   assert(layer && "A null OGRlayer cannot belong to an OGRDataSource" );
   // OGR always refuses "delete 0". *sigh*
@@ -83,14 +83,14 @@ otb::ogr::Layer::const_iterator otb::ogr::Layer::cbegin() const
   return const_iterator(*const_cast <Layer*>(this));
 }
 
-otb::ogr::Layer::iterator otb::ogr::Layer::start(size_t index)
+otb::ogr::Layer::iterator otb::ogr::Layer::start_at(size_t index)
 {
   assert(m_Layer && "OGRLayer not initialized");
   m_Layer->SetNextByIndex(index);
   return iterator(*this);
 }
 
-otb::ogr::Layer::const_iterator otb::ogr::Layer::cstart(size_t index) const
+otb::ogr::Layer::const_iterator otb::ogr::Layer::cstart_at(size_t index) const
 {
   assert(m_Layer && "OGRLayer not initialized");
   m_Layer->SetNextByIndex(index);
@@ -103,7 +103,8 @@ void otb::ogr::Layer::CreateFeature(Feature feature)
   const OGRErr res = m_Layer->CreateFeature(&feature.ogr());
   if (res != OGRERR_NONE)
     {
-    itkGenericExceptionMacro(<< "Cannot create a new feature in the layer <"<<GetName()<<">:" << CPLGetLastErrorMsg());
+    itkGenericExceptionMacro(<< "Cannot create a new feature in the layer <"
+      <<GetName()<<">:" << CPLGetLastErrorMsg());
     }
 }
 
@@ -113,7 +114,8 @@ void otb::ogr::Layer::DeleteFeature(long nFID)
   const OGRErr res = m_Layer->DeleteFeature(nFID);
   if (res != OGRERR_NONE)
     {
-    itkGenericExceptionMacro(<< "Cannot delete the feature <"<<nFID<<"> in the layer <"<<GetName()<<">:" << CPLGetLastErrorMsg());
+    itkGenericExceptionMacro(<< "Cannot delete the feature <"<<nFID<<"> in the layer <"
+      <<GetName()<<">:" << CPLGetLastErrorMsg());
     }
 }
 
@@ -134,7 +136,8 @@ void otb::ogr::Layer::SetFeature(Feature feature)
   const OGRErr res = m_Layer->SetFeature(&feature.ogr());
   if (res != OGRERR_NONE)
     {
-    itkGenericExceptionMacro(<< "Cannot update a feature in the layer <"<<GetName()<<">:" << CPLGetLastErrorMsg());
+    itkGenericExceptionMacro(<< "Cannot update a feature in the layer <"
+      <<GetName()<<">:" << CPLGetLastErrorMsg());
     }
 }
 
@@ -222,7 +225,8 @@ void otb::ogr::Layer::CreateField(
   const OGRErr res = m_Layer->CreateField(const_cast <OGRFieldDefn*>(&field), bApproxOK);
   if (res != OGRERR_NONE)
     {
-    itkGenericExceptionMacro(<< "Cannot create a field in the layer <"<<GetName()<<">:" << CPLGetLastErrorMsg());
+    itkGenericExceptionMacro(<< "Cannot create a field in the layer <"
+      <<GetName()<<">:" << CPLGetLastErrorMsg());
     }
 }
 
@@ -230,31 +234,34 @@ void otb::ogr::Layer::DeleteField(size_t fieldIndex)
 {
   assert(m_Layer && "OGRLayer not initialized");
 #if GDAL_VERSION_NUM < 1900
-  itkGenericExceptionMacro("OGRLayer::AlterFieldDefn is not supported by OGR v"
+  itkGenericExceptionMacro("OGRLayer::DeleteField is not supported by OGR v"
     << GDAL_VERSION_NUM << ". Upgrade to a version >= 1.9.0, and recompile OTB.")
 #else
   const OGRErr res = m_Layer->DeleteField(int(fieldIndex));
   if (res != OGRERR_NONE)
     {
     itkGenericExceptionMacro(<< "Cannot delete the "<<fieldIndex << "th field in the layer <"
-      <<GetName() <<">.");
+      <<GetName() <<">:" << CPLGetLastErrorMsg());
     }
 #endif
 }
 
 void otb::ogr::Layer::AlterFieldDefn(
-  size_t fieldIndex, OGRFieldDefn& newFieldDefn, int nFlags)
+  size_t fieldIndex, OGRFieldDefn const& newFieldDefn, int nFlags)
 {
   assert(m_Layer && "OGRLayer not initialized");
 #if GDAL_VERSION_NUM < 1900
   itkGenericExceptionMacro("OGRLayer::AlterFieldDefn is not supported by OGR v"
     << GDAL_VERSION_NUM << ". Upgrade to a version >= 1.9.0, and recompile OTB.")
 #else
-  const OGRErr res = m_Layer->AlterFieldDefn(int(fieldIndex), &newFieldDefn, nFlags);
+  const OGRErr res = m_Layer->AlterFieldDefn(
+    int(fieldIndex),
+    const_cast <OGRFieldDefn*>(&newFieldDefn),
+    nFlags);
   if (res != OGRERR_NONE)
     {
     itkGenericExceptionMacro(<< "Cannot alter the "<<fieldIndex << "th field in the layer <"
-      <<GetName() <<">.");
+      <<GetName() <<">:" << CPLGetLastErrorMsg());
     }
 #endif
 }
@@ -270,7 +277,7 @@ void otb::ogr::Layer::ReorderField(size_t oldPos, size_t newPos)
   if (res != OGRERR_NONE)
     {
     itkGenericExceptionMacro(<< "Cannot move the "<<oldPos << "th field to the "
-      << newPos << "th position in the layer <" <<GetName() <<">.");
+      << newPos << "th position in the layer <" <<GetName() <<">:" << CPLGetLastErrorMsg());
     }
 #endif
 }
@@ -286,11 +293,22 @@ void otb::ogr::Layer::ReorderFields(int * map)
   if (res != OGRERR_NONE)
     {
     itkGenericExceptionMacro(<< "Cannot reorder the fields of the layer <"
-      <<GetName() <<">.");
+      <<GetName() <<">:" << CPLGetLastErrorMsg());
     }
 #endif
 }
 
+void otb::ogr::Layer::SetIgnoredFields(char const** fieldNames)
+{
+  assert(m_Layer && "OGRLayer not initialized");
+  const OGRErr res = m_Layer->SetIgnoredFields(fieldNames);
+  if (res != OGRERR_NONE)
+    {
+    itkGenericExceptionMacro(<< "Cannot set fields to ignore on the layer <"
+      <<GetName() <<">:" << CPLGetLastErrorMsg());
+    }
+}
+
 OGRwkbGeometryType otb::ogr::Layer::GetGeomType() const
 {
   assert(m_Layer && "OGRLayer not initialized");
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h
index 25682b90609a58868965822d899bb38a08718539..1456a59db7988acab332392ccdfea7b3ef2160e6 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h
@@ -42,17 +42,17 @@ namespace otb { namespace ogr {
  * encapsulation of \c OGRLayer.
  *
  * \note this class is a proxy class on top of an \c OGRLayer.
- * \note It can be copied.
+ * \note It can be copied, and assigned. NEw instances will share the underlying
+ * \c OGRLayer.
  * \note when created from a \c otb::ogr::DataSource::ExecuteSQL, it will
  * automatically manage the release of the underlying \c OGRLayer.
  * \note the default constructor is disabled on purpose
  * \note the destructor automatically generated does everything that is
  * expected.
  *
- * \todo find a way to tell whether the related \c OGRDataSource was released
+ * \todo find a way to be notified when the related \c OGRDataSource is released
  */
 class Layer
-  // : public itk::DataObject
   {
 public:
   /**\name ITK class typedefs */
@@ -62,8 +62,31 @@ public:
 
   /**\name Construction */
   //@{
+  /**
+   * Init constructor with a layer owned by a DataSource.
+   * \param layer \c OGRLayer instance that is owned by a DataSource.
+   * \throw None
+   * On destruction of the proxy class, the internal \c OGRLayer is left alone.
+   *
+   * @warning if the datasource hosting the layer (built with this constructor)
+   * is deleted, the layer won't be usable anymore. Unfortunatelly, there is no
+   * mean to report this to this layer proxy.
+   */
   explicit Layer(OGRLayer* layer);
-  Layer(OGRLayer* layer, OGRDataSource* sourceInChargeOfLifeTime);
+
+  /**
+   * Init constructor for layers that need to be released.
+   * \param layer  \c OGRLayer owned by the client code.
+   * \param sourceInChargeOfLifeTime  reference to the actual \c OGRDataSource
+   * that knows how to release the layer.
+   *
+   * \throw None
+   * \internal
+   * This constructor is meant to be used for wrapping layers coming from \c
+   * OGRDataSource::ExecuteSQL(). It's actually the constructor called by \c
+   * DataSource::ExecuteSQL().
+   */
+  Layer(OGRLayer* layer, OGRDataSource& sourceInChargeOfLifeTime);
   //@}
 
   /**\name Features collection */
@@ -127,7 +150,7 @@ public:
    * \param[in,out] feature feature to set. Upon successful completion, the feature
    * id will be updated (in case it was previously set)
    *
-   * \throw itk::ExceptionObject if the feauture can't be set.
+   * \throw itk::ExceptionObject if the feature can't be set.
    * \pre the Layer need to support <em>OLCRandomWrite</em> capability.
    * \sa OGRLayer::SetFeature
    * \internal
@@ -172,30 +195,70 @@ public:
   OGRLayer & ogr();
 
   /**\name Spatial filter property
-   * \internal the I/O geometry is an undeletable pointer, that may be null.
    * \todo we'll see later if a Geometry capsule is defined, or a
    * \c nondeletable<> pointer type.
+   * \internal
+   * The I/O geometry is an undeletable pointer, that may be null (hence the
+   * need of pointers instead of references).
    */
   //@{
-  OGRGeometry const* GetSpatialFilter() const; // not a ref because it may be null
-  void SetSpatialFilter(OGRGeometry const* spatialFilter); // not a ref because it may be null
-  /// Sets a new rectangular spatial filter.
+  /**
+   * Returns a reference to the current spatial filter, if any.
+   *
+   * \return a reference to the current spatial filter. Spatial filter that isn't
+   * supposed to be modified this way. Use \c SetSpatialFilter or \c
+   * SetSpatialFilterRect for this purpose.
+   * \throw None
+   * \sa OGRLayer::GetSpatialFilter
+   */
+  OGRGeometry const* GetSpatialFilter() const;
+
+  /**
+   * Sets the current spatial filter.
+   * \param[in] spatialFilter  new spatial filter definition, NULL clears the
+   * filter.
+   * \throw None
+   * Replaces the current spatial filter with a clone of the one passed as
+   * parameter. Thus parameter remains the responsibility of the caller.
+   *
+   * The spatial filter is used to filter the \c Feature's obtained when iterating
+   * on the layer.
+   * \note OGR warns us that the test may be incorrectly implemented, and that
+   * we may have false-positives, but no missed shapes.
+   * \sa OGRLayer::SetSpatialFilter
+   */
+  void SetSpatialFilter(OGRGeometry const* spatialFilter);
+  /** Sets a new rectangular spatial filter.
+   * Defines the new filter as a rectangular shape.
+   *
+   * The coordinates used shall be in the same referential as the layer as the
+   * whole (as returned by \c GetSpatialRef()).
+   * \sa OGRLayer::SetSpatialFilterRect
+   */
   void SetSpatialFilterRect(double dfMinX, double dfMinY, double dfMaxX, double dfMaxY);
   //@}
 
-  /**\name Spatial Reference property
+  /**Spatial Reference property.
    * \internal the I/O spatial reference is an undeletable pointer, that may be null.
    * \note read-only property
    */
-  //@{
   OGRSpatialReference const* GetSpatialRef() const;
-  //@}
 
   /**\name Iteration */
   //@{
   /**\ingroup Geometry
    * \class feature_iter
    * Implementation class for \c Feature iterator.
+   * This iterator is a single <em>pass iterator</em>. We may fetch the \c
+   * Feature referenced by an iterator previously stored, but never resume the
+   * iteration after a call to \c Layer::begin(), \c Layer::start(), \c
+   * Layer::CreateFeature(), \c Layer::DeleteFeature(), \c Layer::GetFeature(),
+   * \c Layer::SetFeature(), nor fork the iteration.
+   * \code
+   * iterator b = begin();
+   * iterator i = std::advance(b, 1);
+   * b++; // this is invalid
+   * \endcode
    * \internal
    * \sa otb::ogr::Layer::iterator
    * \sa otb::ogr::Layer::const_iterator
@@ -240,33 +303,147 @@ public:
     };
 
   template <class> friend class feature_iter;
+  /// Features %iterator.
   typedef feature_iter<Feature      > iterator;
+  /// Features const %iterator.
   typedef feature_iter<Feature const> const_iterator;
 
-  const_iterator begin () const { return cbegin(); }
-  const_iterator end   () const { return cend  (); }
+  /** Returns a <em>single-pass</em> %iterator to the start of the sequence.
+   * \sa feature_iter
+   */
   const_iterator cbegin() const;
+  /** Returns the %end %iterator of the sequence.
+   */
   const_iterator cend  () const { return iterator(); }
+  /**\copydoc cbegin */
+  const_iterator begin () const { return cbegin(); }
+  /**\copydoc cend */
+  const_iterator end   () const { return cend  (); }
+  /**\copydoc cbegin */
   iterator       begin ();
+  /**\copydoc cend */
   iterator       end   () { return iterator(); }
 
-  const_iterator start (size_t index) const { return cstart(index); }
-  const_iterator cstart(size_t index) const;
-  iterator       start (size_t index);
+  /** Returns a <em>single-pass</em> %iterator to the i-th \c Feature of the
+   * sequence.
+   * \sa feature_iter
+   * Depending of the actual driver (i.e. \c OGRDriver), this may be done in O(N).
+   */
+  const_iterator cstart_at(size_t index) const;
+  /** \copydoc cstart_at */
+  const_iterator start_at (size_t index) const { return cstart_at(index); }
+  /** \copydoc cstart_at */
+  iterator       start_at (size_t index);
   //@}
 
-  /**\name Features definition */
+  /**\name Features definition
+   * \todo shall we instead inhibit the declaration of the functions when GDAL
+   * version does not match?
+   */
   //@{
+  /** Returns a reference to the layer definition.
+   * @warning the definition obtained shall not be modified. Use the \c *Field
+   * functions instead.
+   * \internal
+   * The return type shall have been const, but unfortunatelly \c OGRFeatureDefn
+   * is not const-correct.
+   * \sa OGRLayer::GetLayerDefn
+   */
   OGRFeatureDefn & GetLayerDefn() const;
 
+  /**
+   * Adds a new field given its definition.
+   * \param[in] field  field definition
+   * \param[in] bApproxOK  If true, the field may be created in a slightly
+   * different form depending on the limitations of the format driver.
+   *
+   * \pre This function shall not be called while there are \c Feature in
+   * existance that were obtained or created with the previous layer definition.
+   * \throw itk::ExceptionObject if the new field cannot be created
+   * \sa OGRLayer::CreateField
+   * \todo move to use \c otb::ogr::FieldDefn
+   */
   void CreateField(OGRFieldDefn const& field, bool bApproxOK = true);
+
+  /**
+   * Deletes a field.
+   * \param[in] fieldIndex  index of the field to remove.
+   *
+   * \pre This function shall not be called while there are \c Feature in
+   * existance that were obtained or created with the previous layer definition.
+   * \throw itk::ExceptionObject if the new field cannot be deleted
+   * \sa OGRLayer::DeleteField
+   * \pre to be available, this function requires OTB to be compiled against OGR
+   * v1.9.0 at least.
+   */
   void DeleteField(size_t fieldIndex);
-  void AlterFieldDefn(size_t fieldIndex, OGRFieldDefn& newFieldDefn, int nFlags);
+
+  /**
+   * Changes the definition of the i-th field.
+   * \param[in] fieldIndex  index of the field to change
+   * \param[in,out] newFieldDefn  definition of the new field.
+   * \param[in] nFlags  combination of \c ALTER_NAME_FLAG, \c ALTER_TYPE_FLAG
+   * and \c ALTER_WIDTH_PRECISION_FLAG to indicate which of the name and/or type
+   * and/or width and precision fields from the new field definition must be
+   * taken into account.
+   *
+   * \pre This function shall not be called while there are \c Feature in
+   * existance that were obtained or created with the previous layer definition.
+   * \throw itk::ExceptionObject if the new field cannot be modified
+   * \sa OGRLayer::AlterFieldDefn
+   * \pre to be available, this function requires OTB to be compiled against OGR
+   * v1.9.0 at least.
+   * \todo move to use \c otb::ogr::FieldDefn
+   */
+  void AlterFieldDefn(size_t fieldIndex, OGRFieldDefn const& newFieldDefn, int nFlags);
+
+  /**
+   * Moves a field from one position to another.
+   * \param[in] oldPos  old field index position
+   * \param[in] newPos  new field index position
+   *
+   * \pre This function shall not be called while there are \c Feature in
+   * existance that were obtained or created with the previous layer definition.
+   * \throw itk::ExceptionObject if the new field cannot be modified
+   * \sa OGRLayer::ReorderField
+   * \pre to be available, this function requires OTB to be compiled against OGR
+   * v1.9.0 at least.
+   */
   void ReorderField(size_t oldPos, size_t newPos);
+
+  /**
+   * Reorder all the fields of the layer.
+   * \param[in] map array that tells the new position of each field.
+   *
+   * \pre This function shall not be called while there are \c Feature in
+   * existance that were obtained or created with the previous layer definition.
+   * \throw itk::ExceptionObject if the new field cannot be modified
+   * \sa OGRLayer::ReorderFields
+   * \pre to be available, this function requires OTB to be compiled against OGR
+   * v1.9.0 at least.
+   */
   void ReorderFields(int *map);
-  void SetIgnoredFields(int *);
+
+  /**
+   * Sets which fields can be omitted when retrieving features from the layer.
+   * \param[in] fieldNames 0-terminated array of the field names to ignore when
+   * fetching features from the layer. 0 to clear the list.
+   * end
+   *
+   * Besides field names of the layers, the following special fields can be
+   * passed: "OGR_GEOMETRY" to ignore geometry and "OGR_STYLE" to ignore layer
+   * style.
+   *
+   * By default, no fields are ignored.
+   * \throw itk::ExceptionObject if the new field cannot be modified
+   * \sa OGRLayer::SetIgnoredFields
+   */
+  void SetIgnoredFields(char const** fieldNames);
   //@}
 
+  /** Returns the type of the geometry stored.
+   * \sa OGRLayer::GetGeomType
+   */
   OGRwkbGeometryType GetGeomType() const;
 private:
   /**