[gdal] 01/06: Imported Upstream version 2.2.0~beta2+dfsg

Bas Couwenberg sebastic at debian.org
Sun Apr 23 16:04:35 UTC 2017


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch experimental-2.2
in repository gdal.

commit b06df1c8ad328df266b8da64134941a7bf085f0a
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Sun Apr 23 15:51:22 2017 +0200

    Imported Upstream version 2.2.0~beta2+dfsg
---
 MIGRATION_GUIDE.TXT                                |  34 +-
 NEWS                                               | 103 +--
 alg/gdalwarpkernel.cpp                             |  14 +-
 alg/gdalwarpoperation.cpp                          |  26 +-
 apps/gdalinfo_lib.cpp                              |  15 +-
 configure                                          |   4 +
 configure.ac                                       |   6 +-
 data/gmlasconf.xml                                 |  15 +-
 data/gmlasconf.xsd                                 |  14 +-
 frmts/dted/dted_create.c                           |  16 +-
 frmts/dted/dteddataset.cpp                         |  11 +-
 frmts/georaster/GNUmakefile                        |   3 +-
 frmts/georaster/cpl_vsil_ocilob.cpp                | 395 +++++++++
 frmts/georaster/frmt_georaster.html                |  42 +-
 frmts/georaster/georaster_dataset.cpp              | 687 +++++++++++++--
 frmts/georaster/georaster_priv.h                   |  40 +-
 frmts/georaster/georaster_rasterband.cpp           |  50 +-
 frmts/georaster/georaster_wrapper.cpp              | 115 ++-
 frmts/georaster/makefile.vc                        |   3 +-
 frmts/georaster/oci_wrapper.cpp                    | 278 +++++-
 frmts/georaster/oci_wrapper.h                      |  21 +-
 frmts/grib/gribdataset.cpp                         |  13 +-
 frmts/gtiff/gt_wkt_srs.cpp                         |  20 +-
 frmts/gtiff/libgeotiff/geo_config.h                |   7 +
 frmts/gtiff/libgeotiff/geo_normalize.h             |  52 +-
 frmts/gtiff/libgeotiff/geo_simpletags.h            |  12 +-
 frmts/gtiff/libgeotiff/geo_tiffp.h                 |  10 +-
 frmts/gtiff/libgeotiff/geotiff.h                   |  48 +-
 frmts/gtiff/libgeotiff/xtiffio.h                   |  16 +-
 frmts/hfa/hfadataset.cpp                           |   8 +-
 frmts/hfa/hfafield.cpp                             |   8 +-
 frmts/jp2kak/jp2kakdataset.cpp                     |  10 +-
 frmts/mbtiles/mbtilesdataset.cpp                   |  34 +-
 frmts/netcdf/frmt_netcdf.html                      |   9 +
 frmts/netcdf/netcdfdataset.cpp                     |  19 +-
 frmts/nitf/frmt_nitf.html                          |  21 +-
 frmts/nitf/nitfdataset.cpp                         | 191 +++-
 frmts/nitf/nitffile.c                              |  13 +-
 frmts/openjpeg/GNUmakefile                         |  13 +-
 frmts/openjpeg/makefile.vc                         |  17 +-
 frmts/openjpeg/openjpegdataset.cpp                 | 172 +++-
 frmts/pdf/pdfio.h                                  |  13 +-
 frmts/plmosaic/plmosaicdataset.cpp                 |  14 +-
 frmts/raw/gtxdataset.cpp                           |   4 +-
 frmts/vrt/vrtderivedrasterband.cpp                 |   4 +-
 gcore/gdal_version.h                               |   6 +-
 gcore/gdaldllmain.cpp                              |   5 +-
 man/man1/gdal-config.1                             |   2 +-
 man/man1/gdal2tiles.1                              |   2 +-
 man/man1/gdal_calc.1                               |   2 +-
 man/man1/gdal_contour.1                            |   2 +-
 man/man1/gdal_edit.1                               |   2 +-
 man/man1/gdal_fillnodata.1                         |   2 +-
 man/man1/gdal_grid.1                               |   2 +-
 man/man1/gdal_merge.1                              |   2 +-
 man/man1/gdal_pansharpen.1                         |   2 +-
 man/man1/gdal_polygonize.1                         |   2 +-
 man/man1/gdal_proximity.1                          |   2 +-
 man/man1/gdal_rasterize.1                          |   2 +-
 man/man1/gdal_retile.1                             |   2 +-
 man/man1/gdal_sieve.1                              |   2 +-
 man/man1/gdal_translate.1                          |   2 +-
 man/man1/gdal_utilities.1                          |   2 +-
 man/man1/gdaladdo.1                                |   2 +-
 man/man1/gdalbuildvrt.1                            |   2 +-
 man/man1/gdalcompare.1                             |   2 +-
 man/man1/gdaldem.1                                 |   2 +-
 man/man1/gdalinfo.1                                |   2 +-
 man/man1/gdallocationinfo.1                        |   2 +-
 man/man1/gdalmanage.1                              |   2 +-
 man/man1/gdalmove.1                                |   2 +-
 man/man1/gdalsrsinfo.1                             |   2 +-
 man/man1/gdaltindex.1                              |   2 +-
 man/man1/gdaltransform.1                           |   2 +-
 man/man1/gdalwarp.1                                |   2 +-
 man/man1/gnm_utilities.1                           |   2 +-
 man/man1/gnmanalyse.1                              |   2 +-
 man/man1/gnmmanage.1                               |   2 +-
 man/man1/nearblack.1                               |   2 +-
 man/man1/ogr2ogr.1                                 |   2 +-
 man/man1/ogr_utilities.1                           |   2 +-
 man/man1/ogrinfo.1                                 |   2 +-
 man/man1/ogrlineref.1                              |   2 +-
 man/man1/ogrmerge.1                                |   2 +-
 man/man1/ogrtindex.1                               |   2 +-
 man/man1/pct2rgb.1                                 |   2 +-
 man/man1/rgb2pct.1                                 |   2 +-
 ogr/ogrgeometryfactory.cpp                         |  13 +-
 .../amigocloud/ogramigoclouddatasource.cpp         |  50 +-
 ogr/ogrsf_frmts/carto/ogrcartodatasource.cpp       |  14 +-
 ogr/ogrsf_frmts/couchdb/ogrcouchdbdatasource.cpp   |  16 +-
 ogr/ogrsf_frmts/csv/ogrcsvdriver.cpp               |   4 +-
 ogr/ogrsf_frmts/elastic/ogrelasticdatasource.cpp   |  14 +-
 ogr/ogrsf_frmts/geojson/ogresrijsonreader.cpp      |  25 +-
 ogr/ogrsf_frmts/geojson/ogrgeojsondatasource.cpp   |   4 +-
 ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp       | 188 +++-
 ogr/ogrsf_frmts/geojson/ogrtopojsonreader.cpp      |  25 +-
 ogr/ogrsf_frmts/gmlas/drv_gmlas.html               |  12 +
 .../gmlas/drv_gmlas_mapping_examples.html          |  79 ++
 .../gmlas/drv_gmlas_metadata_layers.html           |  14 +-
 ogr/ogrsf_frmts/gmlas/ogr_gmlas.h                  |  35 +-
 ogr/ogrsf_frmts/gmlas/ogr_gmlas_consts.h           |   3 +
 ogr/ogrsf_frmts/gmlas/ogrgmlasconf.cpp             |   6 +-
 ogr/ogrsf_frmts/gmlas/ogrgmlasdatasource.cpp       |  18 +-
 ogr/ogrsf_frmts/gmlas/ogrgmlaslayer.cpp            | 363 +++++++-
 ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp           | 221 ++++-
 ogr/ogrsf_frmts/gmlas/ogrgmlasschemaanalyzer.cpp   |  29 +-
 ogr/ogrsf_frmts/gmlas/ogrgmlaswriter.cpp           |   5 +-
 ogr/ogrsf_frmts/gpkg/ogrgeopackagedatasource.cpp   |  41 +-
 ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp   |   6 +-
 ogr/ogrsf_frmts/oci/ogr_oci.h                      |  12 +-
 ogr/ogrsf_frmts/oci/ogrocidatasource.cpp           |   6 +-
 ogr/ogrsf_frmts/oci/ogrocisession.cpp              |  54 +-
 ogr/ogrsf_frmts/oci/ogrociwritablelayer.cpp        |   4 +-
 ogr/ogrsf_frmts/osm/ogrosmdatasource.cpp           |  16 +-
 ogr/ogrsf_frmts/plscenes/ogrplscenesdataset.cpp    |  14 +-
 .../plscenes/ogrplscenesdatav1dataset.cpp          |  18 +-
 ogr/ogrsf_frmts/plscenes/ogrplscenesv1dataset.cpp  |  18 +-
 ogr/ogrsf_frmts/plscenes/ogrplscenesv1layer.cpp    |   8 +-
 ogr/ogrsf_frmts/shape/shapefil.h                   |   8 +-
 ogr/ogrutils.cpp                                   |   6 +-
 port/cpl_string.h                                  |  47 +-
 swig/csharp/ogr/Feature.cs                         |  92 +-
 swig/csharp/ogr/FeatureDefn.cs                     |   8 +-
 swig/csharp/ogr/ogr_wrap.cpp                       | 317 ++-----
 swig/include/ogr.i                                 | 186 ++--
 swig/include/perl/typemaps_perl.i                  |  11 +
 swig/include/python/ogr_python.i                   |  10 +-
 swig/java/javadoc.java                             |  10 +-
 swig/perl/ogr_wrap.cpp                             | 125 +--
 swig/perl/t/ogr.t                                  |   2 +-
 swig/python/extensions/ogr_wrap.cpp                | 961 +++++++++++----------
 swig/python/osgeo/ogr.py                           |  62 +-
 swig/python/samples/validate_gpkg.py               |  56 +-
 134 files changed, 4133 insertions(+), 1814 deletions(-)

diff --git a/MIGRATION_GUIDE.TXT b/MIGRATION_GUIDE.TXT
index a2711d2..562f969 100644
--- a/MIGRATION_GUIDE.TXT
+++ b/MIGRATION_GUIDE.TXT
@@ -10,23 +10,6 @@ and wkbTriangle; and their Z, M and ZM variants (as well as for the type of
 geometry fields). Client code, as well as out-of-tree drivers that support
 writing geometries, must be ready to deal with them.
 
-MIGRATION GUIDE FROM GDAL 2.0 to GDAL 2.1
-------------------------------------------
-
-A) RFC 61: Support for measured geometries
-
-Link: https://trac.osgeo.org/gdal/wiki/rfc61_support_for_measured_geometries
-
-The OGRwkbGeometryType enumeration has been extended with new values for the
-M and ZM variants of the geometry types. Client code may have to be upgraded
-to take into account those new values. Note that the wkbPolyhedralSurface, wkbTIN
-and wkbTriangle types and their Z, M and ZM variants, have also been introduced
-as a provision for a potential support in a future version (they are unused in
-OGR core and drivers for now).
-
-Previously the ESRI Shapefile driver read XYM data as XYZ. Now it is read
-as XYM.
-
 B) RFC 67: Null values in OGR
 
 Link: https://trac.osgeo.org/gdal/wiki/rfc67_nullfieldvalues
@@ -45,6 +28,23 @@ On the writing side, a few drivers will now distinguish between the unset
 and null state, namely GeoJSON, CouchDB, Cloudant, MongoDB, ElasticSearch and
 GML.
 
+MIGRATION GUIDE FROM GDAL 2.0 to GDAL 2.1
+------------------------------------------
+
+A) RFC 61: Support for measured geometries
+
+Link: https://trac.osgeo.org/gdal/wiki/rfc61_support_for_measured_geometries
+
+The OGRwkbGeometryType enumeration has been extended with new values for the
+M and ZM variants of the geometry types. Client code may have to be upgraded
+to take into account those new values. Note that the wkbPolyhedralSurface, wkbTIN
+and wkbTriangle types and their Z, M and ZM variants, have also been introduced
+as a provision for a potential support in a future version (they are unused in
+OGR core and drivers for now).
+
+Previously the ESRI Shapefile driver read XYM data as XYZ. Now it is read
+as XYM.
+
 MIGRATION GUIDE FROM GDAL 1.11 to GDAL 2.0
 ------------------------------------------
 
diff --git a/NEWS b/NEWS
index 2ccc892..4fdd557 100644
--- a/NEWS
+++ b/NEWS
@@ -24,10 +24,14 @@ GDAL/OGR 2.2.0 Release Notes =
         https://trac.osgeo.org/gdal/wiki/rfc63_sparse_datasets_improvements
  * RFC 64: Triangle, Polyhedral surface and TIN
         https://trac.osgeo.org/gdal/wiki/rfc64_triangle_polyhedralsurface_tin
+    ==> this RFC introduces potential backward incompatible behaviour.
+        Consult MIGRATION_GUIDE.txt
  * RFC 66: OGR random layer read/write capabilities
         https://trac.osgeo.org/gdal/wiki/rfc66_randomlayerreadwrite
  * RFC 67: add null field state for OGR features, in addition to unset fields
         https://trac.osgeo.org/gdal/wiki/rfc67_nullfieldvalues
+    ==> this RFC introduces potential backward incompatible behaviour.
+        Consult MIGRATION_GUIDE.txt
  * Upgrade to EPSG database v9.0 (#6772)
  * Python bindings: Global Interpreter Lock (GIL) released before entering GDAL native code (for all, in GDAL module and a few ones in ogr like ogr.Open())
  * Continued major efforts on sanitization of code base
@@ -53,9 +57,9 @@ Build(Unix):
  * configure: make pdfium detection not fail if there are just warnings. And make configure fail if --with-pdfium was required but failed (#6653)
  * Make ./configure --with-xerces fail if not found
  * Don't install script documentation in INST_BIN (github #157)
- * configure: autodetect webp without requiring explicit --with-webp
+ * configure: auto-detect webp without requiring explicit --with-webp
  * configure: use pkg-config for HDF5 detection so that works out of the box on recent Ubuntu
- * autodetect JDK 8 on Ubuntu
+ * auto-detect JDK 8 on Ubuntu
  * MDB: allow libjvm.so to be dlopen'd with --with-jvm-lib=dlopen (Unix only, github #177)
  * configure: delete temporary directories on the mac
  * configure: make sure --with-macosx-framework is correctly defined
@@ -65,9 +69,11 @@ Build(Unix):
  * configure: take into account CXXFLAGS and LDFLAGS in a few more cases (cryptopp, podofo, libdap)
  * Vagrant: all lxc and Hyper-V provider support; use vagrant-cachier for package caching
  * configure: update DWG support to work with Teigha libraries
+ * Internal libgeotiff: hide symbols in --with-hide-internal-symbols mode
+ * Shape: do not export Shapelib symbols for builds --with-hide-internal-symbols (#6860)
 
 Build(Windows):
- * Try to avoid confusiong between libqhull io.h and mingw own io.h (#6590)
+ * Try to avoid confusion between libqhull io.h and mingw own io.h (#6590)
  * update script to generate most recent Visual C++ project files (#6635)
  * fix broken and missing dependencies in makefile.vc
  * add a way to use an external zlib (github #171)
@@ -149,7 +155,7 @@ Core:
  * Average and mode overview/rasterio resampling: correct source pixel computation due to numerical precision issues when downsampling by an integral factor, and also in oversampling use cases (github #156)
  * Overview building: add experimental GDAL_OVR_PROPAGATE_NODATA config option that can be set to YES so that a nodata value in source samples will cause the target pixel to be zeroed. Only implemented for AVERAGE resampling right now
  * GDALValidateOptions(): fix check of min/max values
- * GMLJP2 v2: update to 2.0.1 corigendum and add capability to set gml:RectifiedGrid/gmlcov:rangeType content. Set SRSNAME_FORMAT=OGC_URL by default when converting to GML. Add gml:boundedBy in gmljp2:GMLJP2RectifiedGridCoverage
+ * GMLJP2 v2: update to 2.0.1 corrigendum and add capability to set gml:RectifiedGrid/gmlcov:rangeType content. Set SRSNAME_FORMAT=OGC_URL by default when converting to GML. Add gml:boundedBy in gmljp2:GMLJP2RectifiedGridCoverage
  * GMLJP2 v2: ensure KML root node id unicity when converting annotations on the fly. When generating GML features, make sure that PREFIX and TARGET_NAMESPACE are unique when specifying several documents.
 
 Algorithms:
@@ -179,6 +185,7 @@ Utilities:
  * gdalwarp: allow to set UNIFIED_SRC_NODATA=NO to override the default that set it to YES
  * gdalwarp: fix -to SRC_METHOD=NO_GEOTRANSFORM -to DST_METHOD=NO_GEOTRANSFORM mode (#6721)
  * gdalwarp: add support for shifting the values of input DEM when source and/or target SRS references a proj.4 vertical datum shift grid
+ * gdalwarp: fix crash when -multi and -to RPC_DEM are used together (#6869)
  * gdal_translate: when using -projwin with default nearest neighbour resampling, align on integer source pixels (#6610)
  * gdal_translate & gdalwarp: lower the default value of GDAL_MAX_DATASET_POOL_SIZE to 100 on MacOSX (#6604)
  * gdal_translate: avoid useless directory scanning on GeoTIFF files
@@ -214,7 +221,7 @@ AIGRID driver:
  * fix 2.1.0 regression when reading statistics (.sta) file with only 3 values, and fix <2.1 behaviour to read them in LSB order (#6633)
  
 AAIGRID driver:
- * autodetect Float64 when the nodata value is not representable in the Float32 range
+ * auto-detect Float64 when the nodata value is not representable in the Float32 range
 
 ADRG driver:
  * handle north and south polar zones (ZNA 9 and 18) (#6783)
@@ -222,13 +229,9 @@ ADRG driver:
 ASRP driver:
  * fix georeferencing of polar arc zone images (#6560)
 
-BMP driver:
-
 BPG driver:
 * declare GDALRegister_BPG as C exported for building as a plugin (#6693)
 
-BLX driver:
-
 DIMAP driver:
  * DIMAP: for DIMAP 2, read RPC from RPC_xxxxx.XML file (#6539)
  * DIMAP/Pleiades metadata reader: take into tiling to properly shift RPC (#6293)
@@ -237,7 +240,8 @@ DIMAP driver:
 DODS driver:
  * fix crash on URL that are not DODS servers (#6718)
 
-ECRG driver:
+DTED driver:
+ * correctly create files at latitudes -80, -75, -70 and -50 (#6859)
 
 ECW driver:
  * Add option ECW_ALWAYS_UPWARD=TRUE/FALSE  to work around issues with "Downward" oriented images (#6516).
@@ -248,10 +252,9 @@ ENVI driver:
 
 GeoRaster driver:
  * fix report of rotation (#6593)
-
-GIF driver:
-
-GMT driver:
+ * support for JP2-F compression (#6861)
+ * support direct loading of JPEG-F when blocking=no (#6861)
+ * default blocking increased from 256x256 to 512x512 (#6861)
 
 GPKG driver:
  * implement tiled gridded elevation data extension
@@ -263,8 +266,8 @@ GPKG driver:
 
 GTiff driver:
  * support SPARSE_OK=YES in CreateCopy() mode (and in update mode with the SPARSE_OK=YES open option), by actively detecting blocks filled with 0/nodata about to be written
- * When writing missing blocks (ie non SPARSE case), use the nodata value when defined. Otherwise fallback to 0 as before.
- * in FillEmptyTiles() (ie in the TIFF non-sparse mode), avoid writing zeroes to file so as to speed up file creation when filesystem supports ... sparse files
+ * When writing missing blocks (i.e. non SPARSE case), use the nodata value when defined. Otherwise fallback to 0 as before.
+ * in FillEmptyTiles() (i.e. in the TIFF non-sparse mode), avoid writing zeroes to file so as to speed up file creation when filesystem supports ... sparse files
  * add write support for half-precision floating point (Float32 with NBITS=16)
  * handle storing (and reading) band color interpretation in GDAL internal metadata when it doesn't match the capabilities of the TIFF format, such as B,G,R ordering (#6651)
  * Fix RasterIO() reported when downsampling a RGBA JPEG compressed TIFF file (#6943)
@@ -288,6 +291,7 @@ GTiff driver:
  * in COPY_SRC_OVERVIEWS=YES mode, set nodata value on overview bands
  * read GCPs in ESRI <GeodataXform> .aux.xml
  * explicitly write YCbCrSubsampling tag, so as to avoid (latest version of) libtiff to try reading the first strip to guess it. Helps performance for cloud optimized geotiffs
+ * map D_North_American_1927 datum citation name to OGC North_American_Datum_1927 so that datum is properly recognized (#6863)
  * Internal libtiff. Resync with CVS (post 4.0.7)
  * Internal libtiff: fix 1.11 regression that prevents from reading one-strip files that have no StripByteCounts tag (#6490)
 
@@ -313,8 +317,6 @@ HDF4 driver:
 HDF5 driver:
  * correct number of GCPs to avoid dummy trailing (0,0)->(0,0,0) and remove +180 offset applied to GCP longitude. Add instead a heuristics to determine if the product is crossing the antimeridian, and a HDF5_SHIFT_GCPX_BY_180 config option to be able to override the heuristics (#6666)
 
-HF2 driver:
-
 HFA driver:
  * fix reading and writing of TOWGS84 parameters (github #132)
  * export overview type from HFA files to GDAL metadata as OVERVIEWS_ALGORITHM (github #135)
@@ -329,8 +331,6 @@ Idrisi driver:
 ILWIS driver:
  * avoid IniFile::Load() to set the bChanged flag, so as to avoid a rewrite of files when just opening datasets
 
-INGR driver:
-
 ISCE driver:
  * fix computation of line offset for multi-band BIP files, and warn if detecting a wrong file produced by GDAL 2.1.0 (#6556)
  * fix misbehaviour on big endian hosts
@@ -348,7 +348,7 @@ JP2ECW driver:
  * fix crash when translating a Float64 raster (at least with SDK 3.3)
 
 JP2KAK driver:
- * add support for Kakadu v7.8
+ * add support for Kakadu v7.9.  v7.8 should not be used.  It has a bug fixed in v7.9
  * catch exceptions in jp2_out.write_header()
 
 JP2OpenJPEG driver:
@@ -357,8 +357,6 @@ JP2OpenJPEG driver:
  * for single-line organized images, such as found in some GRIB2 JPEG2000 images, use a Wx1 block size to avoid huge performance issues (#6719)
   * ignore warnings related to empty tag-trees.
 
-JPEG driver:
-
 JPIPKAK driver:
  * fix random crashes JPIP in multi-tread environment (#6809)
 
@@ -372,15 +370,13 @@ KMLSuperOverlay driver:
 LAN driver:
  * remove wrong byte-swapping for big-endian hosts
 
-LCP driver:
-
-Leveller driver:
-
 MAP driver:
  * change logic to detect image file when its path is not absolute
 
 MBTiles driver:
  * on opening if detecting 3 bands, expose 4 bands since there might be transparent border tiles (#6836)
+ * fix setting of minzoom when computing overviews out of order
+ * do not open .mbtiles that contain vector tiles, which are not supported by the driver
 
 MEM driver:
  * disable R/W mutex for tiny performance increase in resampled RasterIO
@@ -406,23 +402,24 @@ NetCDF driver:
  * fix erroneous detection of a non-longitude X axis as a longitude axis that caused a shift of 360m on the georeferencing (#6759)
  * read/write US_survey_foot unit for linear units of projection
  * apply 'add_offset' and 'scale_factor' on x and y variables when present, such as in files produced by NOAA from the new GOES-16 (GOES-R) satellite (github #200)
-
-NGSGEOID driver:
+ * add a HONOUR_VALID_RANGE=YES/NO open option to control whether pixel values outside of the validity range should be set to the nodata value (#6857)
 
 NITF driver:
+ * add support for writing JPEG2000 compressed images with JP2OpenJPEG driver
+ * fix writing with JP2KAK driver (emit codestream only instead of JP2 format)
+ * fix setting of NBPR/NBPC/NPPBH/NPPBV fields for JPEG2000 (fixes #4322); in JP2ECW case, make sure that the default PROFILE=NPJE implies 1024 block size at the NITF level
  * implement creation of RPC00B TRE for RPC metadata in CreateCopy() mode
  * add support for reading&writing _rpc.txt files
  * nitf_spec.xml: Add support for MTIRPB TRE in NITF image segment. Also makes minor change to BLOCKA to include default values (github #127)
  * nitf_spec.xml: add IMASDA and IMRFCA TREs
  * GetFileList(): Small optimization to avoid useless file probing.
 
-Northwoord driver:
-
-NTv2 driver:
-
 NWT_GRD:
  * detect short writes
 
+OpenJPEG driver:
+ * support direct extracting of GeoRaster JP2-F BLOB (#6861)
+ 
 PCIDSK driver:
  * handle Exceptions returned from destructor and check access rights in setters (github #183)
 
@@ -431,13 +428,9 @@ PDF driver:
  * implement reading from/writing to PAM for geotransform and projection (#6603)
  * prevent crashes on dataset reopening in case of short write
 
-PDS driver:
-
 PLScenes driver:
  * add a METADATA open option
 
-PNG driver:
-
 PostgisRaster driver:
  * fix potential crash when one tile has a lower number of bands than the max of the table (#6267)
 
@@ -447,8 +440,6 @@ R driver:
 Raw drivers:
  * prevent crashes on dataset closing in case of short write
 
-RIK driver:
-
 RMF driver:
  * fix wrong counter decrement that caused compressed RMF to be incorrectly decompressed (github #153)
  * fix load/store inversion of cm and dm units in MTW files (github #162)
@@ -476,8 +467,6 @@ SRTMHGT driver:
  * accept filenames like NXXEYYY.SRTMGL1.hgt (#6614)
  * handle files for latitude >= 50 (#6840)
 
-VICAR driver:
-
 VRT driver:
  * add default pixel functions: real, imag, complex, mod, phase, conj, etc... for complex data types (github #141)
  * avoid useless floating point values in SrcRect / DstRect (#6568)
@@ -529,10 +518,11 @@ if operating on two layers with same geom dim.
  * OGR SQL: add comparisons on date / datetime (#6810)
  * OGR SQL: increase efficiency of DISTINCT operator
  * OGREnvelope: change initialization to fix issue when getting MULTIPOINT(0 0,1 1) envelope (#6841)
+ * OGRParse: fix parsing logic to avoid false positive detection of string as datetime (#6867)
 
 OGRSpatialReference:
- * Upgrade to EPSG database v8.9
- * OGRCT: upgrade LIBNAME of mingw and cygwin to libproj-9.dll and cygproj-9.dll to be uptodate with proj 4.9.X (recommended method is using ./configure --with-static-proj4 instead) (#6501)
+ * Upgrade to EPSG database v9.0 (#6772)
+ * OGRCT: upgrade LIBNAME of mingw and cygwin to libproj-9.dll and cygproj-9.dll to be up-to-date with proj 4.9.X (recommended method is using ./configure --with-static-proj4 instead) (#6501)
  * importFromESRI(): fix import of multi line MERCATOR SRS (#6523)
  * morphToESRI(): correctly compute standard_parallel_1 of Mercator(2SP) projection from scale factor of Mercator(1SP) (#6456, #4861)
  * exportToProj4(): recognize explicit OSR_USE_ETMERC=NO to avoid using etmerc with proj >= 4.9.3
@@ -594,6 +584,7 @@ GeoJSON driver:
  * writer: add a RFC7946=YES creation option (#6705)
  * read and write 'name' and 'description' members at FeatureCollection level
  * fix field type detection when first value of a field is null (#6517)
+ * improve/fix field type promotion
  * fix wrong behaviour when there's a 'id' at Feature level and 'id' or 'ID' field in properties (#6538)
  * in case top level id is a negative integer, put the value in a 'id' attribute (#6538)
  * ESRI Json reader: support multilinestring from esriGeometryPolyline
@@ -601,6 +592,7 @@ GeoJSON driver:
  * Add CPL_json_object_object_get() and use it, to avoid deprecation warnings on json_object_object_get()
  * TopoJSON reader: sanitize invalid polygons (such as found in the 'TopoJSON' layer of http://bl.ocks.org/mbostock/raw/4090846/us.json)
  * writer: fix segfaults on NULL geometry with -lco WRITE_BBOX=YES (#6698)
+ * writer: fix crash if NATIVE_MEDIA_TYPE creation option is specified alone
  * Add support of TopoJSON without 'transform' element (github #192)
  * don't set SRS if 'crs' set to null (github #206)
 
@@ -653,16 +645,12 @@ GPKG driver:
  * use GEOMETRYCOLLECTION instead of GEOMCOLLECTION for SQL and gpkg_geometry_columns.geometry_type_name
  * do not warn if gpkg_metadata extension declared
 
-GPX driver:
-
 ILI driver:
  * ILI1: fix crash in JoinSurfaceLayer() when the multicurve of the feature of the poSurfaceLineLayer layer is empty (#6688)
  * ILI1: make polygon reconstruction in Surface layers robust to curves not in natural order (#6728)
  * ILI2: assign FID to features (#6839)
  * ILI2: fix crashing bug in Create() if model file not specified
 
-JML driver:
-
 KML driver:
  * add a DOCUMENT_ID datasource creation option to set the id of the root <Document> node
 
@@ -671,8 +659,6 @@ LIBKML driver:
  * add a DOCUMENT_ID datasource creation option to set the id of the root <Document> node
  * emit style related errors as warnings to make datasets openable by SWIG bindings (#6850)
 
-Memory driver:
-
 MITAB driver:
  * limit (width, precision) of numeric fields on creation to (20,16) for compatibility with MapInfo (#6392)
  * add support for oblique stereographic (#6598)
@@ -691,8 +677,6 @@ MySQL driver:
 NAS driver:
  * support multiple 'anlass' in updates
 
-NTF driver:
-
 NWT_GRD:
  * add write support (#6533)
 
@@ -700,8 +684,8 @@ OCI driver:
  * Add options for faster feature loading (#6606)
  * add WORKSPACE open option
  * correctly handle OFTInteger64 case in loader layer (bug found by cppcheck multiCondition)
-
-ODBC driver:
+ * support for long identifiers (up to 128 long) when running of 12.2 or + (#6866)
+ * OCILOB VSIL driver: new driver to streams in and out of Oracle BLOB as a GDAL large virtual file system (#6861)
 
 ODS driver:
  * fix FID filtering (#6788)
@@ -730,8 +714,6 @@ PG driver:
  * fix insertion of binary/bytea content in non-copy mode (#6566)
  * fix errors caused by missing geometry_columns/spatial_ref_sys tables in non PostGIS databases, that prevent reading more than 500 features (QGIS #10904)
 
-PGDump driver:
-
 PLScenes driver:
  * add HTTP retry logic (#6655)
  * V0 API: workaround limitations on filtering on image_statistics.image_quality (#6657)
@@ -766,8 +748,8 @@ SOSI driver:
 SQLite/Spatialite driver:
  * do not emit error when running ExecuteSQL() with a spatial filter on an empty layer (#6639)
  * add read/write support for String/Integer/Integer64/RealList types as serialized JSon arrays
- * Spatiliate: avoid crash when creating layer with geom_type = wkbCurve (fixes #6660)
- * Spatiliate: do not report some BLOB columns as geometry columns of tables/views (when found before the geometry column(s)) (#6695, #6659)
+ * Spatialite: avoid crash when creating layer with geom_type = wkbCurve (fixes #6660)
+ * Spatialite: do not report some BLOB columns as geometry columns of tables/views (when found before the geometry column(s)) (#6695, #6659)
  * fix update of features with multiple geometry columns (#6696)
  * speed-up dataset closing when creating a database with many spatial layers
  * Spatialite: avoid spatial views to cause layers 'layer_name(geometry_name)' to be publicly listed (#6740)
@@ -780,8 +762,6 @@ SQLite/Spatialite driver:
  * Update layer statistics for Spatialite 4 DB (#6838)
  * Remove traces of support of SQLite < 3.6.0
 
-SXF driver:
-
 VFK driver:
  * allow reading multiple VFK files into single DB support amendment VFK files
  * recreate DB in the case that it's outdated (VFK DB created by previous versions of GDAL)
@@ -800,8 +780,6 @@ WFS driver:
 XLSX driver:
  * only list worksheets (and no charts) as layers (#6680)
 
-XPlane driver:
-
 == SWIG Language Bindings ==
 
 All bindings:
@@ -840,6 +818,7 @@ Python bindings:
  * fix gdal.DEMProcessingOptions(zeroForFlat=True) (#6775)
  * fix 'import osgeo.gdal_array' with python3 and SWIG 3.0.10 (#6801)
  * allow gdal.FileFromMemBuffer() to use buffer > 2GB (#6828)
+ * accept unicode strings as field name argument in Feature (like SetField, GetField, etc...) and FeatureDefn methods
 
 = GDAL/OGR 2.1.0 Release Notes =
 
@@ -3192,7 +3171,7 @@ SQLite/Spatialite driver:
  * Spatialite: fix insertion in spatial_ref_sys to avoid issues with non-numeric authority codes (auth_srid)
  * Spatialite: make creation of database much faster with spatialite 4.1 by using InitSpatialMetaData(1) (#5270)
  * Spatialite: use thread-safe initialization for spatialite >= 4.1.2
- * avoid spatiliate views to emit (hidden) errors that cause troubles to MapServer OGR input driver (#5060)
+ * avoid Spatialite views to emit (hidden) errors that cause troubles to MapServer OGR input driver (#5060)
  * attempt to make VirtualOGR (and thus sqlite dialect) work even with a libsqlite3 compiled with SQLITE_OMIT_LOAD_EXTENSION (on Unix only)
  * add warning when calling CreateField() with a field name that is 'ROWID' since it can cause corrupted spatial index
  * serialize StringList as non-truncated strings
diff --git a/alg/gdalwarpkernel.cpp b/alg/gdalwarpkernel.cpp
index 1e1d121..e1ad0a5 100644
--- a/alg/gdalwarpkernel.cpp
+++ b/alg/gdalwarpkernel.cpp
@@ -71,7 +71,7 @@
 
 #endif
 
-CPL_CVSID("$Id: gdalwarpkernel.cpp 37976 2017-04-13 12:34:40Z rouault $");
+CPL_CVSID("$Id: gdalwarpkernel.cpp 38093 2017-04-21 21:02:44Z rouault $");
 
 static const double BAND_DENSITY_THRESHOLD = 0.0000000001;
 static const float SRC_DENSITY_THRESHOLD =  0.000000001f;
@@ -4660,6 +4660,18 @@ static CPL_INLINE bool GWKCheckAndComputeSrcOffsets(
     if( !_pabSuccess[_iDstX] )
         return false;
 
+    // If this happens this is likely the symptom of a bug somewhere.
+    if( CPLIsNan(_padfX[_iDstX]) || CPLIsNan(_padfY[_iDstX]) )
+    {
+        static bool bNanCoordFound = false;
+        if( !bNanCoordFound )
+        {
+            CPLDebug("WARP", "NaN coordinate found.");
+            bNanCoordFound = true;
+        }
+        return false;
+    }
+
 /* -------------------------------------------------------------------- */
 /*      Figure out what pixel we want in our source raster, and skip    */
 /*      further processing if it is well off the source image.          */
diff --git a/alg/gdalwarpoperation.cpp b/alg/gdalwarpoperation.cpp
index cc9fd64..44584fa 100644
--- a/alg/gdalwarpoperation.cpp
+++ b/alg/gdalwarpoperation.cpp
@@ -49,7 +49,7 @@
 #include "ogr_api.h"
 #include "ogr_core.h"
 
-CPL_CVSID("$Id: gdalwarpoperation.cpp 37002 2016-12-22 23:15:16Z goatbar $");
+CPL_CVSID("$Id: gdalwarpoperation.cpp 38093 2017-04-21 21:02:44Z rouault $");
 
 struct _GDALWarpChunk {
     int dx, dy, dsx, dsy;
@@ -1690,11 +1690,22 @@ CPLErr GDALWarpOperation::WarpRegionToBuffer(
 /* -------------------------------------------------------------------- */
     if( nSrcXSize == 0 && nSrcYSize == 0 )
     {
+        // TODO: This taking of the warp mutex is suboptimal. We could get rid
+        // of it, but that would require making sure ComputeSourceWindow()
+        // uses a different pTransformerArg than the warp kernel.
+        if( hWarpMutex != NULL && !CPLAcquireMutex( hWarpMutex, 600.0 ) )
+        {
+            CPLError( CE_Failure, CPLE_AppDefined,
+                      "Failed to acquire WarpMutex in WarpRegion()." );
+            return CE_Failure;
+        }
         const CPLErr eErr =
             ComputeSourceWindow( nDstXOff, nDstYOff, nDstXSize, nDstYSize,
                                  &nSrcXOff, &nSrcYOff,
                                  &nSrcXSize, &nSrcYSize,
                                  &nSrcXExtraSize, &nSrcYExtraSize, NULL );
+        if( hWarpMutex != NULL )
+            CPLReleaseMutex( hWarpMutex );
         if( eErr != CE_None )
             return eErr;
     }
@@ -2471,6 +2482,19 @@ CPLErr GDALWarpOperation::ComputeSourceWindow(
             continue;
         }
 
+        // If this happens this is likely the symptom of a bug somewhere.
+        if( CPLIsNan(padfX[i]) || CPLIsNan(padfY[i]) )
+        {
+            static bool bNanCoordFound = false;
+            if( !bNanCoordFound )
+            {
+                CPLDebug("WARP", "NaN coordinate found.");
+                bNanCoordFound = true;
+            }
+            nFailedCount++;
+            continue;
+        }
+
         if( !bGotInitialPoint )
         {
             bGotInitialPoint = true;
diff --git a/apps/gdalinfo_lib.cpp b/apps/gdalinfo_lib.cpp
index 7af3ba0..9c7d262 100644
--- a/apps/gdalinfo_lib.cpp
+++ b/apps/gdalinfo_lib.cpp
@@ -55,11 +55,12 @@
 #include "ogr_api.h"
 #include "ogr_json_header.h"
 #include "ogr_srs_api.h"
+#include "ogrgeojsonreader.h"
 #include "ogrgeojsonwriter.h"
 
 using std::vector;
 
-CPL_CVSID("$Id: gdalinfo_lib.cpp 37502 2017-02-28 10:25:01Z rouault $");
+CPL_CVSID("$Id: gdalinfo_lib.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 /*! output format */
 typedef enum {
@@ -1587,17 +1588,7 @@ static void GDALInfoPrintMetadata( const GDALInfoOptions* psOptions,
                 }
                 else if( bMDIsJson )
                 {
-                    json_tokener* jstok = json_tokener_new();
-                    poValue = json_tokener_parse_ex(jstok, papszMetadata[i], -1);
-                    if( jstok->err != json_tokener_success)
-                    {
-                        CPLError(CE_Failure, CPLE_AppDefined,
-                                    "JSon parsing error: %s (at offset %d)",
-                                    json_tokener_error_desc(jstok->err),
-                                    jstok->char_offset);
-                        poValue = NULL;
-                    }
-                    json_tokener_free(jstok);
+                    OGRJSonParse(papszMetadata[i], &poValue, true);
                     break;
                 }
                 else
diff --git a/configure b/configure
index 8061957..7af467f 100755
--- a/configure
+++ b/configure
@@ -19884,6 +19884,10 @@ $as_echo_n "checking whether we should hide internal symbols... " >&6; }
 $as_echo "yes" >&6; }
         CFLAGS="$CFLAGS -fvisibility=hidden"
         CXXFLAGS="$CXXFLAGS -fvisibility=hidden"
+        CFLAGS_NOFTRAPV="$CFLAGS_NOFTRAPV -fvisibility=hidden"
+        CXXFLAGS_NOFTRAPV="$CXXFLAGS_NOFTRAPV -fvisibility=hidden"
+        CXXFLAGS_NO_LTO_IF_AVX_NONDEFAULT="$CXXFLAGS_NO_LTO_IF_AVX_NONDEFAULT -fvisibility=hidden"
+        CXXFLAGS_NO_LTO_IF_SSSE3_NONDEFAULT="$CXXFLAGS_NO_LTO_IF_SSSE3_NONDEFAULT -fvisibility=hidden"
     else
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
diff --git a/configure.ac b/configure.ac
index 7edff14..e3e83e8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 dnl ***************************************************************************
-dnl $Id: configure.ac 37968 2017-04-12 07:16:55Z rouault $
+dnl $Id: configure.ac 38000 2017-04-14 11:50:06Z rouault $
 dnl
 dnl Project:  GDAL
 dnl Purpose:  Configure source file.
@@ -767,6 +767,10 @@ if test "$with_hide_internal_symbols" = "yes"; then
         AC_MSG_RESULT([yes])
         CFLAGS="$CFLAGS -fvisibility=hidden"
         CXXFLAGS="$CXXFLAGS -fvisibility=hidden"
+        CFLAGS_NOFTRAPV="$CFLAGS_NOFTRAPV -fvisibility=hidden"
+        CXXFLAGS_NOFTRAPV="$CXXFLAGS_NOFTRAPV -fvisibility=hidden"
+        CXXFLAGS_NO_LTO_IF_AVX_NONDEFAULT="$CXXFLAGS_NO_LTO_IF_AVX_NONDEFAULT -fvisibility=hidden"
+        CXXFLAGS_NO_LTO_IF_SSSE3_NONDEFAULT="$CXXFLAGS_NO_LTO_IF_SSSE3_NONDEFAULT -fvisibility=hidden"
     else
         AC_MSG_RESULT([no])
     fi
diff --git a/data/gmlasconf.xml b/data/gmlasconf.xml
index cd8fe47..01ba5f0 100644
--- a/data/gmlasconf.xml
+++ b/data/gmlasconf.xml
@@ -39,16 +39,15 @@
             <!-- Maximum number of fields allowed for element flattening -->
             <MaximumNumberOfFields>10</MaximumNumberOfFields>
 
-            <!--
             <Namespaces>
-                <Namespace prefix="..." uri="..."/>
+                <Namespace prefix="swe" uri="http://www.opengis.net/swe/2.0"/>
             </Namespaces>
-            -->
+
             <!-- Exception to MaximumNumberOfFields:
                 force this element(s) to be flattened even if they have more elements -->
-            <!--
-            <ForceFlatteningXPath>...</ForceFlatteningXPath>
-            -->
+
+            <ForceFlatteningXPath>swe:values</ForceFlatteningXPath>
+
             <!-- Exception to MaximumNumberOfFields:
                 prevent this element(s) from being flattened even if they have less elements -->
             <!--
@@ -58,6 +57,7 @@
 
         <SWEProcessing>
             <Activation>ifSWENamespaceFoundInTopElement</Activation>
+            <ProcessDataRecord>true</ProcessDataRecord>
             <ProcessDataArray>true</ProcessDataArray>
         </SWEProcessing>
     </LayerBuildingRules>
@@ -147,12 +147,11 @@
         <XPath>swe:Quantity/@optional</XPath>
         <XPath>swe:Quantity/@id</XPath>
         <XPath>swe:Quantity/swe:identifier</XPath>
-        <XPath>swe:Quantity/@definition</XPath>
+        <!-- <XPath>swe:Quantity/@definition</XPath> -->
         <XPath>swe:Quantity/swe:label</XPath>
         <XPath>swe:Quantity/swe:nilValues</XPath>
         <XPath>swe:Quantity/swe:constraint</XPath>
         <XPath>swe:Quantity/swe:quality</XPath>
-        <XPath>swe:Quantity/swe:extension</XPath>
     </IgnoredXPaths>
 
     <!-- Section for GMLAS writer config -->
diff --git a/data/gmlasconf.xsd b/data/gmlasconf.xsd
index aee082a..ef3122b 100644
--- a/data/gmlasconf.xsd
+++ b/data/gmlasconf.xsd
@@ -317,7 +317,8 @@
                       <xs:annotation>
                         <xs:documentation>
                             XPath of element that will be considered for flattening
-                            even if it has more than MaximumNumberOfFields fields.
+                            even if it has more than MaximumNumberOfFields fields,
+                            or if it is referenced several times by other elements.
                             Note: other constraints might make it impossible to
                             flatten it, for example if it has repeated elements.
                         </xs:documentation>
@@ -367,11 +368,20 @@
                         </xs:restriction>
                       </xs:simpleType>
                     </xs:element>
+                    <xs:element name="ProcessDataRecord" type="xs:boolean"
+                                minOccurs="0" maxOccurs="unbounded">
+                      <xs:annotation>
+                        <xs:documentation>
+                            If swe:DataRecord must be parsed. Default is true.
+                        </xs:documentation>
+                      </xs:annotation>
+                    </xs:element>
                     <xs:element name="ProcessDataArray" type="xs:boolean"
                                 minOccurs="0" maxOccurs="unbounded">
                       <xs:annotation>
                         <xs:documentation>
-                            If swe:DataArray must be parsed. Default is tru.
+                            If swe:DataArray and swe:DataStream must be parsed.
+                            Default is true.
                         </xs:documentation>
                       </xs:annotation>
                     </xs:element>
diff --git a/frmts/dted/dted_create.c b/frmts/dted/dted_create.c
index d77d709..5c78792 100644
--- a/frmts/dted/dted_create.c
+++ b/frmts/dted/dted_create.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: dted_create.c 36380 2016-11-21 10:21:20Z rouault $
+ * $Id: dted_create.c 38003 2017-04-14 13:28:13Z rouault $
  *
  * Project:  DTED Translator
  * Purpose:  Implementation of DTEDCreate() portion of DTED API.
@@ -30,7 +30,7 @@
 #include "dted_api.h"
 #include <assert.h>
 
-CPL_CVSID("$Id: dted_create.c 36380 2016-11-21 10:21:20Z rouault $");
+CPL_CVSID("$Id: dted_create.c 38003 2017-04-14 13:28:13Z rouault $");
 
 #define DTED_ABS_VERT_ACC "NA  "
 #define DTED_SECURITY     "U"
@@ -118,7 +118,7 @@ const char *DTEDCreate( const char *pszFilename, int nLevel,
 {
     VSILFILE     *fp;
     unsigned char achRecord[3601*2 + 12];
-    int         nXSize, nYSize, iProfile;
+    int         nXSize, nYSize, nReferenceLat, iProfile;
 
 /* -------------------------------------------------------------------- */
 /*      Establish resolution.                                           */
@@ -144,13 +144,15 @@ const char *DTEDCreate( const char *pszFilename, int nLevel,
                  nLevel );
     }
 
-    if( ABS(nLLOriginLat) >= 80 )
+    nReferenceLat = nLLOriginLat < 0 ? - (nLLOriginLat + 1) : nLLOriginLat;
+
+    if( nReferenceLat >= 80 )
         nXSize = (nXSize - 1) / 6 + 1;
-    else if( ABS(nLLOriginLat) >= 75 )
+    else if( nReferenceLat >= 75 )
         nXSize = (nXSize - 1) / 4 + 1;
-    else if( ABS(nLLOriginLat) >= 70 )
+    else if( nReferenceLat >= 70 )
         nXSize = (nXSize - 1) / 3 + 1;
-    else if( ABS(nLLOriginLat) >= 50 )
+    else if( nReferenceLat >= 50 )
         nXSize = (nXSize - 1) / 2 + 1;
 
 /* -------------------------------------------------------------------- */
diff --git a/frmts/dted/dteddataset.cpp b/frmts/dted/dteddataset.cpp
index b8ba463..16ceda5 100644
--- a/frmts/dted/dteddataset.cpp
+++ b/frmts/dted/dteddataset.cpp
@@ -35,7 +35,7 @@
 #include <cstdlib>
 #include <algorithm>
 
-CPL_CVSID("$Id: dteddataset.cpp 36501 2016-11-25 14:09:24Z rouault $");
+CPL_CVSID("$Id: dteddataset.cpp 38003 2017-04-14 13:28:13Z rouault $");
 
 /************************************************************************/
 /* ==================================================================== */
@@ -668,13 +668,14 @@ DTEDCreateCopy( const char * pszFilename, GDALDataset *poSrcDS,
 /*     Check horizontal source size.                                    */
 /* -------------------------------------------------------------------- */
     int expectedXSize;
-    if( std::abs(nLLOriginLat) >= 80 )
+    int nReferenceLat = nLLOriginLat < 0 ? - (nLLOriginLat + 1) : nLLOriginLat;
+    if( nReferenceLat >= 80 )
         expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 6 + 1;
-    else if( std::abs(nLLOriginLat) >= 75 )
+    else if( nReferenceLat >= 75 )
         expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 4 + 1;
-    else if( std::abs(nLLOriginLat) >= 70 )
+    else if( nReferenceLat >= 70 )
         expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 3 + 1;
-    else if( std::abs(nLLOriginLat) >= 50 )
+    else if( nReferenceLat >= 50 )
         expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 2 + 1;
     else
         expectedXSize = poSrcDS->GetRasterYSize();
diff --git a/frmts/georaster/GNUmakefile b/frmts/georaster/GNUmakefile
index de5aed6..810cc60 100644
--- a/frmts/georaster/GNUmakefile
+++ b/frmts/georaster/GNUmakefile
@@ -9,7 +9,8 @@ endif
 OBJ		=	georaster_dataset.o \
 			georaster_rasterband.o \
 			oci_wrapper.o \
-			georaster_wrapper.o
+			georaster_wrapper.o \
+			cpl_vsil_ocilob.o
 
 CPPFLAGS	:=	$(GDAL_INCLUDE) $(OCI_INCLUDE) $(XTRA_OPT) $(CPPFLAGS) -fPIC
 
diff --git a/frmts/georaster/cpl_vsil_ocilob.cpp b/frmts/georaster/cpl_vsil_ocilob.cpp
new file mode 100644
index 0000000..bb31841
--- /dev/null
+++ b/frmts/georaster/cpl_vsil_ocilob.cpp
@@ -0,0 +1,395 @@
+/**********************************************************************
+ * $Id: cpl_vsil_ocilob.cpp $
+ *
+ * Project:  CPL - Common Portability Library
+ * Purpose:  Implement VSI large file api for Oracle OCI LOB
+ * Author:   Ivan Lucena, <ivan dot lucena at oracle dot com>
+ *
+ **********************************************************************
+ * Copyright (c) 2015, Ivan Lucena, <ivan dot lucena at oracle dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#include "cpl_port.h"
+#include "cpl_error.h"
+#include "cpl_vsi_virtual.h"
+
+#include "georaster_priv.h"
+
+CPL_CVSID("$Id: cpl_vsil_ocilob.cpp $");
+
+// *****************************************************************************
+//                                                             WSIOCILobFSHandle
+// *****************************************************************************
+
+class WSIOCILobFSHandle : public VSIFilesystemHandler
+{
+
+public:
+                              WSIOCILobFSHandle();
+    virtual                  ~WSIOCILobFSHandle();
+
+    virtual VSIVirtualHandle *Open( const char *pszFilename, 
+                                    const char *pszAccess,
+                                    bool bSetError ) override;
+    virtual int               Stat( const char *pszFilename,
+                                    VSIStatBufL *pStatBuf, int nFlags ) override;
+
+private:
+
+    OWConnection*     poConnection;
+    OWStatement*      poStatement;
+    OCILobLocator*    phLocator;
+
+    char**            ParseIdentificator( const char* pszFilename );
+};
+
+// *****************************************************************************
+//                                                               VSIOCILobHandle
+// *****************************************************************************
+
+class VSIOCILobHandle : public VSIVirtualHandle
+{
+  private:
+
+    OWConnection*     poConnection;
+    OWStatement*      poStatement;
+    OCILobLocator*    phLocator;
+    GUIntBig          nFileSize;
+    GUIntBig          nCurOff;
+    boolean           bUpdate;
+
+  public:
+                      VSIOCILobHandle( OWConnection* poConnectionIn,
+                                       OWStatement* poStatementIn,
+                                       OCILobLocator* phLocatorIn,
+                                       boolean bUpdateIn );
+    virtual          ~VSIOCILobHandle();
+
+    virtual int       Seek( vsi_l_offset nOffset, int nWhence ) override;
+    virtual vsi_l_offset Tell() override;
+    virtual size_t    Read( void *pBuffer, size_t nSize, size_t nMemb ) override;
+    virtual size_t    Write( const void *pBuffer, size_t nSize, size_t nMemb ) override;
+    virtual int       Eof() override;
+    virtual int       Close() override;
+};
+
+// ****************************************************************************
+// Implementation                                             WSIOCILobFSHandle
+// ****************************************************************************
+
+// ----------------------------------------------------------------------------
+//                                                          WSIOCILobFSHandle()
+// ----------------------------------------------------------------------------
+
+WSIOCILobFSHandle::WSIOCILobFSHandle()
+{
+    poStatement  = NULL;
+    phLocator    = NULL;
+    poConnection = NULL;
+}
+
+// -----------------------------------------------------------------------------
+//                                                          ~WSIOCILobFSHandle()
+// -----------------------------------------------------------------------------
+
+WSIOCILobFSHandle::~WSIOCILobFSHandle()
+{
+    if( phLocator )
+    {
+        OWStatement::Free( &phLocator, 1 );
+    }
+
+    if( poStatement )
+    {
+        delete poStatement;
+    }
+
+    if( poConnection )
+    {
+        delete poConnection;
+    }
+}
+
+// -----------------------------------------------------------------------------
+//                                                          ParseIdentificator()
+// -----------------------------------------------------------------------------
+
+char** WSIOCILobFSHandle::ParseIdentificator( const char* pszFilename )
+{
+    if( strncmp(pszFilename, "/vsiocilob/", strlen("/vsiocilob/") ) != 0 )
+    {
+        return NULL;
+    }
+
+    char** papszParam = CSLTokenizeString2( 
+                            &pszFilename[strlen("/vsiocilob/")], ",",
+                            CSLT_HONOURSTRINGS | CSLT_ALLOWEMPTYTOKENS |
+                            CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES );
+
+    if( CSLCount( papszParam ) < 6 )
+    {
+        CSLDestroy( papszParam );
+        return NULL;
+    }
+
+    return papszParam;
+}
+
+// -----------------------------------------------------------------------------
+//                                                                        Open()
+// -----------------------------------------------------------------------------
+
+VSIVirtualHandle* WSIOCILobFSHandle::Open( const char* pszFilename, 
+                                           const char* pszAccess,
+                                           bool /* bSetError*/ )
+{
+    char** papszParam = ParseIdentificator( pszFilename );
+
+    if( ! papszParam )
+    {
+        return NULL;
+    }
+
+    if( ! EQUAL( papszParam[5], "noext" ) )
+    {
+        CSLDestroy( papszParam );
+        return NULL;
+    }
+
+    poConnection = new OWConnection( papszParam[0],
+                                     papszParam[1],
+                                     papszParam[2] );
+
+    if( ! poConnection->Succeeded() )
+    {
+        CSLDestroy( papszParam );
+        return NULL;
+    }
+
+    const char *pszUpdate = "";
+    boolean bUpdate = false;
+
+    if( strchr(pszAccess, 'w') != NULL ||
+        strchr(pszAccess, '+') != NULL )
+    {
+        pszUpdate = "for update";
+        bUpdate = true;
+    }
+
+    poStatement = poConnection->CreateStatement( CPLSPrintf( 
+                    "select rasterblock from %s where rasterid = %s and rownum = 1 %s", 
+                    papszParam[3], papszParam[4], pszUpdate ) );
+
+    poStatement->Define( &phLocator );
+
+    CSLDestroy( papszParam );
+
+    if( ! poStatement->Execute() )
+    {
+        return NULL;
+    }
+
+    return new VSIOCILobHandle( poConnection, poStatement, phLocator, bUpdate );
+}
+
+// -----------------------------------------------------------------------------
+//                                                                        Stat()
+// -----------------------------------------------------------------------------
+
+int WSIOCILobFSHandle::Stat( const char* pszFilename,
+                             VSIStatBufL* pStatBuf,
+                             int nFlags )
+{
+    (void) nFlags;
+
+    memset( pStatBuf, 0, sizeof(VSIStatBufL) );
+
+    char** papszParam = ParseIdentificator( pszFilename );
+
+    if( ! papszParam )
+    {
+        return -1;
+    }
+
+    if(  strcmp( papszParam[5], "noext" ) != 0 )
+    {
+        return -1;
+    }
+
+    CSLDestroy( papszParam );
+
+    if( poStatement && phLocator )
+    {
+        pStatBuf->st_size = poStatement->GetBlobLength( phLocator );
+    }
+
+    pStatBuf->st_mode = S_IFREG;
+
+    return 0;
+}
+
+// ****************************************************************************
+// Implementation                                               VSIOCILobHandle
+// ****************************************************************************
+
+// ----------------------------------------------------------------------------
+//                                                            VSIOCILobHandle()
+// ----------------------------------------------------------------------------
+
+VSIOCILobHandle::VSIOCILobHandle( OWConnection* poConnectionIn,
+                                  OWStatement* poStatementIn,
+                                  OCILobLocator* phLocatorIn,
+                                  boolean bUpdateIn )
+{
+    this->poConnection = poConnectionIn;
+    this->poStatement  = poStatementIn;
+    this->phLocator    = phLocatorIn;
+    this->bUpdate      = bUpdateIn;
+
+    nCurOff     = 0;
+
+    nFileSize   = poStatement->GetBlobLength( phLocator );
+}
+
+// ----------------------------------------------------------------------------
+//                                                           ~VSIOCILobHandle()
+// ----------------------------------------------------------------------------
+
+VSIOCILobHandle::~VSIOCILobHandle()
+{
+}
+
+// ----------------------------------------------------------------------------
+//                                                                       Seek()
+// ----------------------------------------------------------------------------
+
+int VSIOCILobHandle::Seek( vsi_l_offset nOffset, int nWhence )
+{
+    if (nWhence == SEEK_END)
+    {
+        nOffset = poStatement->GetBlobLength( phLocator );
+    }
+
+    if (nWhence == SEEK_CUR)
+    {
+        nOffset += nCurOff;
+    }
+
+    nCurOff = nOffset;
+
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+//                                                                       Tell()
+// ----------------------------------------------------------------------------
+
+vsi_l_offset VSIOCILobHandle::Tell()
+{
+    return nCurOff;
+}
+
+// ----------------------------------------------------------------------------
+//                                                                       Read()
+// ----------------------------------------------------------------------------
+
+size_t VSIOCILobHandle::Read( void* pBuffer, size_t nSize, size_t nCount )
+{
+    GUIntBig  nBytes = ( nSize * nCount );
+
+    if( nBytes == 0 )
+    {
+        return 0;
+    }
+
+    GUIntBig nRead = poStatement->ReadBlob( phLocator,
+                                            pBuffer,
+                                            (nCurOff + 1),
+                                            nBytes  );
+
+    nCurOff += (GUIntBig) nRead;
+
+    return (size_t) ( nRead / nSize );
+}
+
+// ----------------------------------------------------------------------------
+//                                                                      Write()
+// ----------------------------------------------------------------------------
+
+size_t VSIOCILobHandle::Write( const void * pBuffer,
+                               size_t nSize,
+                               size_t nCount )
+{
+    GUIntBig  nBytes = ( nSize * nCount );
+
+    if( nBytes == 0 )
+    {
+        return 0;
+    }
+
+    GUIntBig nWrite = poStatement->WriteBlob( phLocator,
+                                              (void*) pBuffer,
+                                              (nCurOff + 1),
+                                              nBytes );
+
+    nCurOff += (GUIntBig) nWrite;
+
+    return (size_t) ( nWrite / nSize );
+}
+
+// ----------------------------------------------------------------------------
+//                                                                        Eof()
+// ----------------------------------------------------------------------------
+
+int VSIOCILobHandle::Eof()
+{
+    return (int) ( nCurOff >= nFileSize );
+}
+
+// ----------------------------------------------------------------------------
+//                                                                      Close()
+// ----------------------------------------------------------------------------
+
+int VSIOCILobHandle::Close()
+{
+    if( bUpdate )
+    {
+        poConnection->Commit();
+    }
+
+    return 0;
+}
+
+// -----------------------------------------------------------------------------
+//                                                      VSIInstallStdinHandler()
+// -----------------------------------------------------------------------------
+
+/**
+ * \brief Install /vsiocilob/ virtual file system handler
+ *
+ * A special file handler that allows reading from Oracle's LOB objects.
+ *
+ * @since GDAL 2.0.0
+ */
+void VSIInstallOCILobHandler()
+{
+    VSIFileManager::InstallHandler( "/vsiocilob/", new WSIOCILobFSHandle );
+}
diff --git a/frmts/georaster/frmt_georaster.html b/frmts/georaster/frmt_georaster.html
index 3dc9327..c5f3b7f 100644
--- a/frmts/georaster/frmt_georaster.html
+++ b/frmts/georaster/frmt_georaster.html
@@ -119,9 +119,10 @@ gdal_translate -of georaster landsat_825.tif
 geor:scott/tiger at orcl,landsat,raster \<br>
   -co INSERT="(ID, RASTER) VALUES (2,</span><span style="font-family: Courier New,Courier,monospace;"></span><span style="font-family: Courier New,Courier,monospace;">SDO_GEOR.INIT()</span><span style="font-family: Courier New,Courier,monospace;"></span><span style="font-family: Courier New,Courier,monospace;">)"</span><br>
 <ul>
-  <li><strong>COMPRESS</strong>: Compression options, JPEG-F,
-DEFLATE or NONE. The two JPEG options are lossy, meaning that the
-original pixel values are changed.</li>
+  <li><strong>COMPRESS</strong>: Compression options, JPEG-F, JP2-F,
+DEFLATE or NONE. The JPEG-F options is lossy, meaning that the
+original pixel values are changed. The JP2-F compression is lossless
+if JP2_QUALITY=100.</li>
   <li><strong>GENPYRAMID</strong>: Generate pyramid after a GeoRaster object have been loaded to the database.
 The content of that parameter must be the resampling method of
 choice NN (nearest neighbor) , BILINEAR, BIQUADRATIC, CUBIC, AVERAGE4 or AVERAGE16. If GENPYRLEVELS is not
@@ -130,6 +131,41 @@ informed the PL/SQL function sdo_geor.generatePyramid will calculate the number
 If GENPYRAMID is not informed the resample method NN (nearest neighbor) will apply.</li>
   <li><strong>QUALITY</strong>: Quality compression option for JPEG
 ranging from 0 to 100. The default is 75.</li>
+
+
+<li><p><b>JP2_QUALITY=float_value,float_value,...</b> 
+Only if COMPRESS=JP2-f 
+: Percentage between 0 and 100.
+A value of 50 means the file will be half-size in comparison to uncompressed data,
+33 means 1/3, etc.. Defaults to 25 (unless the dataset is made of a single band
+with color table, in which case the default quality is 100).
+</li>
+
+<li><p><b>JP2_REVERSIBLE=YES/NO</b> 
+Only if COMPRESS=JP2-f 
+: YES means use of reversible 5x3 integer-only
+filter, NO use of the irreversible DWT 9-7. Defaults to NO  (unless the dataset
+is made of a single band with color table, in which case reversible filter is
+used).</p></li>
+
+<li><p><b>JP2_RESOLUTIONS=int_value</b> 
+Only if COMPRESS=JP2-f 
+: Number of resolution levels. Default value
+is selected such the smallest overview of a tile is no bigger than 128x128.</p></li>
+
+<li><p><b>JP2_BLOCKXSIZE=int_value</b> 
+Only if COMPRESS=JP2-f 
+: Tile width. Defaults to 1024.</p></li>
+
+<li><p><b>JP2_BLOCKYSIZE=int_value</b> 
+Only if COMPRESS=JP2-f 
+: Tile height. Defaults to 1024.</p></li>
+
+<li><p><b>JP2_PROGRESSION=LRCP/RLCP/RPCL/PCRL/CPRL</b> 
+Only if COMPRESS=JP2-f 
+: Progession order. Defaults
+to LRCP.</p></li>
+
   <li><strong>NBITS</strong>: Sub byte data type, options: 1, 2 or 4.</li>
   <li><strong>SPATIALEXTENT</strong>: Generate Spatial Extents. The default for that options is
 TRUE, that means that this option only need to be informed to force the Spatial Extent to
diff --git a/frmts/georaster/georaster_dataset.cpp b/frmts/georaster/georaster_dataset.cpp
index 884ee31..26b8dd7 100644
--- a/frmts/georaster/georaster_dataset.cpp
+++ b/frmts/georaster/georaster_dataset.cpp
@@ -29,6 +29,9 @@
  *****************************************************************************/
 
 #include "cpl_error.h"
+#include "cpl_vsi_virtual.h"
+#include "gdaljp2metadata.h"
+#include "cpl_list.h"
 
 #include "gdal.h"
 #include "gdal_frmts.h"
@@ -37,7 +40,7 @@
 
 #include "georaster_priv.h"
 
-CPL_CVSID("$Id: georaster_dataset.cpp 36763 2016-12-09 22:10:55Z rouault $");
+CPL_CVSID("$Id: georaster_dataset.cpp 38020 2017-04-14 21:40:01Z rouault $");
 
 //  ---------------------------------------------------------------------------
 //                                                           GeoRasterDataset()
@@ -60,6 +63,7 @@ GeoRasterDataset::GeoRasterDataset()
     pasGCPList          = NULL;
     poMaskBand          = NULL;
     bApplyNoDataArray   = false;
+    poJP2Dataset        = NULL;
 }
 
 //  ---------------------------------------------------------------------------
@@ -83,6 +87,11 @@ GeoRasterDataset::~GeoRasterDataset()
         delete poMaskBand;
     }
 
+    if( poJP2Dataset )
+    {
+        delete poJP2Dataset;
+    }
+    
     CPLFree( pszProjection );
     CSLDestroy( papszSubdatasets );
 }
@@ -150,6 +159,7 @@ GDALDataset* GeoRasterDataset::Open( GDALOpenInfo* poOpenInfo )
     //  -------------------------------------------------------------------
 
     GeoRasterDataset *poGRD = new GeoRasterDataset();
+
     if( ! poGRD )
     {
         return NULL;
@@ -227,6 +237,22 @@ GDALDataset* GeoRasterDataset::Open( GDALOpenInfo* poOpenInfo )
     }
 
     //  -------------------------------------------------------------------
+    //  Open for JPEG 2000 compression for reading
+    //  -------------------------------------------------------------------
+
+    if( EQUAL( poGRW->sCompressionType.c_str(), "JP2-F" ) &&
+        poGRD->eAccess == GA_ReadOnly )
+    {
+        poGRD->JP2_Open( poOpenInfo->eAccess );
+
+        if( ! poGRD->poJP2Dataset )
+        {
+            delete poGRD;
+            return NULL;            
+        }
+    }
+
+    //  -------------------------------------------------------------------
     //  Load mask band
     //  -------------------------------------------------------------------
 
@@ -237,7 +263,7 @@ GDALDataset* GeoRasterDataset::Open( GDALOpenInfo* poOpenInfo )
     {
         poGRD->poMaskBand = new GeoRasterRasterBand( poGRD, 0, DEFAULT_BMP_MASK );
     }
-
+    
     //  -------------------------------------------------------------------
     //  Check for filter Nodata environment variable, default is YES
     //  -------------------------------------------------------------------
@@ -249,17 +275,17 @@ GDALDataset* GeoRasterDataset::Open( GDALOpenInfo* poOpenInfo )
     {
         poGRD->bApplyNoDataArray = true;
     }
+
     //  -------------------------------------------------------------------
     //  Create bands
     //  -------------------------------------------------------------------
 
     int i = 0;
-    int nBand = 0;
 
-    for( i = 0; i < poGRD->nBands; i++ )
+    for( i = 1; i <= poGRD->nBands; i++ )
     {
-        nBand = i + 1;
-        poGRD->SetBand( nBand, new GeoRasterRasterBand( poGRD, nBand, 0 ) );
+        poGRD->SetBand( i, new GeoRasterRasterBand( poGRD, i, 0 , 
+                                                    poGRD->poJP2Dataset) );
     }
 
     //  -------------------------------------------------------------------
@@ -268,21 +294,21 @@ GDALDataset* GeoRasterDataset::Open( GDALOpenInfo* poOpenInfo )
 
     if( poGRW->nBandBlockSize == 1 )
     {
-        poGRD->SetMetadataItem( "INTERLEAVE", "BAND", "IMAGE_STRUCTURE" );
+        poGRD->SetMetadataItem( "INTERLEAVE", "BSQ", "IMAGE_STRUCTURE" );
     }
     else
     {
         if( EQUAL( poGRW->sInterleaving.c_str(), "BSQ" ) )
         {
-            poGRD->SetMetadataItem( "INTERLEAVE", "BAND", "IMAGE_STRUCTURE" );
+            poGRD->SetMetadataItem( "INTERLEAVE", "BSQ", "IMAGE_STRUCTURE" );
         }
         else if( EQUAL( poGRW->sInterleaving.c_str(), "BIP" ) )
         {
-            poGRD->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" );
+            poGRD->SetMetadataItem( "INTERLEAVE", "PIB", "IMAGE_STRUCTURE" );
         }
         else if( EQUAL( poGRW->sInterleaving.c_str(), "BIL" ) )
         {
-            poGRD->SetMetadataItem( "INTERLEAVE", "LINE", "IMAGE_STRUCTURE" );
+            poGRD->SetMetadataItem( "INTERLEAVE", "BIL", "IMAGE_STRUCTURE" );
         }
     }
 
@@ -291,9 +317,9 @@ GDALDataset* GeoRasterDataset::Open( GDALOpenInfo* poOpenInfo )
 
     if( STARTS_WITH_CI(poGRW->sCompressionType.c_str(), "JPEG") )
     {
-        poGRD->SetMetadataItem( "COMPRESS_QUALITY",
+        poGRD->SetMetadataItem( "COMPRESSION_QUALITY",
             CPLGetXMLValue( poGRW->phMetadata,
-            "rasterInfo.compression.quality", "0" ), "IMAGE_STRUCTURE" );
+            "rasterInfo.compression.quality", "undefined" ), "IMAGE_STRUCTURE" );
     }
 
     if( EQUAL( poGRW->sCellDepth.c_str(), "1BIT" ) )
@@ -335,6 +361,9 @@ GDALDataset* GeoRasterDataset::Open( GDALOpenInfo* poOpenInfo )
 
     poGRD->SetMetadataItem( "WKT", poGRW->sWKText.c_str(), "ORACLE" );
 
+    poGRD->SetMetadataItem( "COMPRESSION", 
+        poGRW->sCompressionType.c_str(), "ORACLE" );
+
     poGRD->SetMetadataItem( "METADATA", pszDoc, "ORACLE" );
 
     CPLFree( pszDoc );
@@ -347,6 +376,441 @@ GDALDataset* GeoRasterDataset::Open( GDALOpenInfo* poOpenInfo )
 }
 
 //  ---------------------------------------------------------------------------
+//                                                                    JP2Open()
+//  ---------------------------------------------------------------------------
+
+void GeoRasterDataset::JP2_Open( GDALAccess /* eAccess */ )
+{
+    GDALDriver* poJP2Driver = NULL;
+
+    static const char * const apszDrivers[] = { "JP2OPENJPEG", "JP2ECW", "JP2MRSID",
+                                                "JPEG2000", "JP2KAK", NULL };
+
+    // Find at least one available JP2 driver
+
+    for( int iDriver = 0; apszDrivers[iDriver] != NULL; iDriver++ )
+    {
+        poJP2Driver = (GDALDriver*) GDALGetDriverByName(apszDrivers[iDriver]);
+
+        if( poJP2Driver )
+        {
+            break;
+        }
+    }
+
+    // If JP2 driver is installed, try to open the LOB via VSIOCILOB handler
+
+    poJP2Dataset = NULL;
+
+    if( poJP2Driver )
+    {
+        CPLString osDSName;
+
+        osDSName.Printf( "/vsiocilob/%s,%s,%s,%s,%d,noext",
+                          poGeoRaster->poConnection->GetUser(),
+                          poGeoRaster->poConnection->GetPassword(),
+                          poGeoRaster->poConnection->GetServer(),
+                          poGeoRaster->sDataTable.c_str(),
+                          poGeoRaster->nRasterId );
+
+        poJP2Dataset = (GDALDataset*) GDALOpenEx( osDSName.c_str(), 
+                                                  GDAL_OF_RASTER,
+                                                  apszDrivers,
+                                                  NULL, NULL );
+    }
+
+    // Report error
+
+    if( ! poJP2Dataset )
+    {
+        CPLError( CE_Failure, CPLE_AppDefined,
+                "Unable to open JPEG2000 image within GeoRaster dataset.\n%s",
+                 ( ! poJP2Driver ) ?
+        "No JPEG2000 capable driver (JP2OPENJPEG,, JP2ECW, JP2MRSID, etc...) is available." :
+        "One or several JPEG2000 capable drivers are available but the lob could not be "
+        "opened successfully." );
+    }
+}
+
+//  ---------------------------------------------------------------------------
+//                                                              JP2CreateCopy()
+//  ---------------------------------------------------------------------------
+
+void GeoRasterDataset::JP2_CreateCopy( GDALDataset* poJP2DS,
+                                       char** papszOptions,
+                                       int* pnResolutions,
+                                       GDALProgressFunc pfnProgress,
+                                       void* pProgressData )
+{
+    GDALDriver* poJP2Driver = NULL;
+
+    static const char * const apszDrivers[] = { "JP2OPENJPEG", "JP2ECW", "JP2MRSID",
+                                                "JPEG2000", "JP2KAK", NULL };
+
+    // Find at least one available JP2 driver
+
+    for( int iDriver = 0; apszDrivers[iDriver] != NULL; iDriver++ )
+    {
+        poJP2Driver = (GDALDriver*) GDALGetDriverByName(apszDrivers[iDriver]);
+
+        if( poJP2Driver )
+        {
+            break;
+        }
+    }
+
+    // If a JP2 driver is installed calls driver's CreateCopy
+
+    poJP2Dataset = NULL;
+
+    if( poJP2Driver )
+    {
+        char** papszOpt = NULL;
+
+        const char* pszFetched  = CSLFetchNameValue( papszOptions, "JP2_BLOCKXSIZE" );
+
+        if( pszFetched )
+        {
+            papszOpt = CSLAddNameValue( papszOpt, "BLOCKXSIZE",  pszFetched );
+            papszOpt = CSLAddNameValue( papszOpt, "TILE_HEIGHT", pszFetched );
+        }
+
+        CPLDebug("GEOR","JP2_BLOCKXSIZE %s", pszFetched );
+
+        pszFetched = CSLFetchNameValue( papszOptions, "JP2_BLOCKYSIZE" );
+
+        if( pszFetched )
+        {
+            papszOpt = CSLAddNameValue( papszOpt, "BLOCKYSIZE",  pszFetched );
+            papszOpt = CSLAddNameValue( papszOpt, "TILE_WIDTH",  pszFetched );
+        }
+
+        pszFetched = CSLFetchNameValue( papszOptions, "JP2_QUALITY" );
+
+        if( pszFetched )
+        {
+            papszOpt = CSLAddNameValue( papszOpt, "QUALITY", pszFetched );
+
+            if( STARTS_WITH_CI( pszFetched, "100" ) )
+            {
+                papszOpt = CSLAddNameValue( papszOpt, "REVERSIBLE",  "TRUE" ); 
+            }
+
+            poGeoRaster->nCompressQuality = atoi( pszFetched );
+        }
+        else
+        {
+            poGeoRaster->nCompressQuality = 25; // JP2OpenJPEG default...
+        }
+
+        pszFetched = CSLFetchNameValue( papszOptions, "JP2_REVERSIBLE" );
+
+        if( pszFetched )
+        {
+            papszOpt = CSLAddNameValue( papszOpt, "REVERSIBLE", pszFetched );
+        }
+
+        pszFetched = CSLFetchNameValue( papszOptions, "JP2_RESOLUTIONS" );
+
+        if( pszFetched )
+        {
+            papszOpt = CSLAddNameValue( papszOpt, "RESOLUTIONS", pszFetched );
+            papszOpt = CSLAddNameValue( papszOpt, "RESOLUTIONS_LEVELS", pszFetched );
+            papszOpt = CSLAddNameValue( papszOpt, "LAYERS", pszFetched );
+        }
+
+        pszFetched = CSLFetchNameValue( papszOptions, "JP2_PROGRESSION" );
+
+        if( pszFetched )
+        {
+            papszOpt = CSLAddNameValue( papszOpt, "PROGRESSION", pszFetched );
+        }
+
+        papszOpt = CSLAddNameValue( papszOpt, "CODEC",       "JP2" ); 
+        papszOpt = CSLAddNameValue( papszOpt, "GeoJP2",      "NO" ); 
+        papszOpt = CSLAddNameValue( papszOpt, "GMLJP2",      "NO" ); 
+        papszOpt = CSLAddNameValue( papszOpt, "YCBCR420",    "NO" );
+        papszOpt = CSLAddNameValue( papszOpt, "TARGET",      "0" ); 
+
+        CPLPushErrorHandler( CPLQuietErrorHandler );
+
+        CPLString osDSName;
+
+        osDSName.Printf( "/vsiocilob/%s,%s,%s,%s,%d,noext",
+                          poGeoRaster->poConnection->GetUser(),
+                          poGeoRaster->poConnection->GetPassword(),
+                          poGeoRaster->poConnection->GetServer(),
+                          poGeoRaster->sDataTable.c_str(),
+                          poGeoRaster->nRasterId );
+
+        poJP2Dataset = (GDALDataset*) GDALCreateCopy( poJP2Driver, 
+                                                      osDSName.c_str(), 
+                                                      poJP2DS,
+                                                      false,
+                                                      (char**) papszOpt,
+                                                      pfnProgress,
+                                                      pProgressData );
+
+        CPLPopErrorHandler();
+
+        CSLDestroy( papszOpt );
+    }
+
+    if( ! poJP2Dataset )
+    {
+        CPLError( CE_Failure, CPLE_AppDefined,
+                "Unable to copy JPEG2000 image into GeoRaster dataset.\n%s",
+                 ( ! poJP2Driver ) ?
+        "No JPEG2000 capable driver (JP2OPENJPEG, JP2ECW, JP2MRSID, etc...) is available." :
+        "One or several JPEG2000 capable drivers are available but the file could not be "
+        "opened successfully." );
+        return;
+    }
+
+    // Retrieve the number of resolutions based on the number of overviews
+
+    CPLPushErrorHandler( CPLQuietErrorHandler );
+
+    *pnResolutions = poJP2Dataset->GetRasterBand(1)->GetOverviewCount() + 1;
+
+    delete poJP2Dataset;
+
+    CPLPopErrorHandler(); // Avoid showing warning regards writing aux.xml file
+
+    poJP2Dataset = NULL;
+}
+
+//  ---------------------------------------------------------------------------
+//                                                             JP2_CopyDirect()
+//  ---------------------------------------------------------------------------
+
+boolean GeoRasterDataset::JP2_CopyDirect( const char* pszJP2Filename,
+                                          int* pnResolutions,
+                                          GDALProgressFunc pfnProgress,
+                                          void* pProgressData )
+{
+    char** papszFileList = GetFileList();
+    
+    if( CSLCount(papszFileList) == 0 )
+    {
+        return false;
+    }
+    
+    VSILFILE *fpInput  = VSIFOpenL( pszJP2Filename, "r" );
+    VSILFILE *fpOutput = VSIFOpenL( papszFileList[0], "wb" );    
+
+    size_t nCache = (size_t) ( GDALGetCacheMax() * 0.25 );
+
+    void *pBuffer = (GByte*) VSIMalloc( sizeof(GByte) * nCache );
+
+    GDALJP2Box oBox( fpInput );
+
+    (void) oBox.ReadFirst();
+
+    GUInt32   nLBox;
+    GUInt32   nTBox;
+
+    int       nBoxCount = 0;
+
+    while( strlen(oBox.GetType()) > 0 )
+    {
+        nBoxCount++;
+
+        if( EQUAL( oBox.GetType(), "jp  " ) ||
+            EQUAL( oBox.GetType(), "ftyp" ) ||
+            EQUAL( oBox.GetType(), "jp2h" ) )
+        {
+            size_t nDataLength = (size_t) oBox.GetDataLength();
+
+            size_t nSize = VSIFReadL( pBuffer, 1, nDataLength, fpInput);
+ 
+            if ( nSize != nDataLength )
+            {
+                CPLError( CE_Warning, CPLE_AppDefined, 
+                          "amount read differs from JP2 Box data length" );
+            }
+
+            nLBox = (int) nDataLength + 8;
+            nLBox = CPL_MSBWORD32( nLBox );
+
+            memcpy( &nTBox, oBox.GetType(), 4 );
+
+            VSIFWriteL( &nLBox, 4, 1, fpOutput );
+            VSIFWriteL( &nTBox, 4, 1, fpOutput );
+            VSIFWriteL( pBuffer, 1, nSize, fpOutput );
+        }
+
+        if( EQUAL( oBox.GetType(), "jp2c" ) )
+        {
+            size_t nCount = 0;
+            size_t nSize = 0;
+            size_t nDataLength = oBox.GetDataLength();
+ 
+            nLBox = (int) nDataLength + 8;
+            nLBox = CPL_MSBWORD32( nLBox );
+
+            memcpy( &nTBox, oBox.GetType(), 4 );
+
+            VSIFWriteL( &nLBox, 4, 1, fpOutput );
+            VSIFWriteL( &nTBox, 4, 1, fpOutput );
+
+            while( nCount < nDataLength )
+            {
+                size_t nChunk = (size_t) MIN( nCache, nDataLength - nCount );
+
+                nSize = VSIFReadL( pBuffer, 1, nChunk, fpInput );
+
+                if ( nSize != nChunk )
+                {
+                    CPLError( CE_Warning, CPLE_AppDefined, 
+                              "amount read differs from JP2 data length" );
+                }
+
+                VSIFWriteL( pBuffer, 1, nSize, fpOutput ); 
+
+                nCount += nSize;
+
+                pfnProgress( (float) nCount / (float) nDataLength, 
+                             NULL, pProgressData );
+            }
+        }
+
+        if( ! oBox.ReadNext() )
+        {
+            break;
+        }
+    }
+
+    VSIFCloseL( fpInput );
+    VSIFCloseL( fpOutput );
+
+    CSLDestroy( papszFileList );
+    CPLFree( pBuffer );
+
+    // Retrieve the number of resolutions based on the number of overviews
+
+    JP2_Open( GA_ReadOnly );
+
+    if( poJP2Dataset )
+    {
+        *pnResolutions = poJP2Dataset->GetRasterBand(1)->GetOverviewCount() + 1;
+
+        delete poJP2Dataset;
+        poJP2Dataset = NULL;
+    }
+
+    return (nBoxCount > 0);
+}
+
+//  ---------------------------------------------------------------------------
+//                                                             JPG_CopyDirect()
+//  ---------------------------------------------------------------------------
+
+boolean GeoRasterDataset::JPEG_CopyDirect( const char* pszJPGFilename,
+                                           GDALProgressFunc pfnProgress,
+                                           void* pProgressData )
+{
+    OWConnection*  poConnection  = poGeoRaster->poConnection;
+    OWStatement*   poStmt = NULL;
+    OCILobLocator* poLocator;
+    
+    poStmt = poConnection->CreateStatement( CPLSPrintf( 
+                   "select rasterblock from %s where rasterid = %d "
+                   "and rownum = 1 for update",
+                   poGeoRaster->sDataTable.c_str(),
+                   poGeoRaster->nRasterId ) );
+    
+    poStmt->Define( &poLocator );
+
+    if( poStmt->Execute() )
+    {
+        VSILFILE *fpInput = VSIFOpenL( pszJPGFilename, "r" );
+
+        size_t nCache = (size_t) ( GDALGetCacheMax() * 0.25 );
+
+        void *pBuffer = (GByte*) VSIMalloc( sizeof(GByte) * nCache );
+
+        VSIFSeekL( fpInput, 0L, SEEK_END);
+
+        size_t nCount = 0;
+        size_t nSize = 0;
+        size_t nDataLength = VSIFTellL( fpInput );
+
+        VSIFSeekL( fpInput, 0L, SEEK_SET );
+
+        GUIntBig nWrite = (GUIntBig) 0;
+        GUIntBig nCurOff = (GUIntBig) 0;
+
+        while( nCount < nDataLength )
+        {
+            size_t nChunk = (size_t) MIN( nCache, nDataLength - nCount );
+
+            nSize = VSIFReadL( pBuffer, 1, nChunk, fpInput );
+
+            if ( nSize != nChunk )
+            {
+                CPLError( CE_Warning, CPLE_AppDefined, 
+                          "amount read differs from JPG length" );
+            }
+
+            nWrite = poStmt->WriteBlob( poLocator,
+                                        (void*) pBuffer,
+                                        (nCurOff + 1),
+                                        nSize );
+
+            nCurOff += nWrite;
+            nCount  += nSize;
+
+            pfnProgress( (float) nCount / (float) nDataLength, 
+                         NULL, pProgressData );
+        }
+        
+        VSIFCloseL( fpInput );
+
+        CPLFree( pBuffer );
+        
+        return true;
+    }            
+
+    if( poLocator )
+    {
+        OWStatement::Free( &poLocator, 1 );
+    }
+    
+    if( poStmt )
+    {
+        delete poStmt;
+    }    
+        
+    return false;
+}
+
+//  ---------------------------------------------------------------------------
+//                                                                GetFileList()
+//  ---------------------------------------------------------------------------
+
+char** GeoRasterDataset::GetFileList()
+{
+    char** papszFileList = NULL;
+    
+    if( EQUAL( poGeoRaster->sCompressionType.c_str(), "JP2-F" ) )
+    {
+        CPLString osDSName;
+
+        osDSName.Printf( "/vsiocilob/%s,%s,%s,%s,%d,noext",
+                this->poGeoRaster->poConnection->GetUser(),
+                this->poGeoRaster->poConnection->GetPassword(),
+                this->poGeoRaster->poConnection->GetServer(),
+                this->poGeoRaster->sDataTable.c_str(),
+                this->poGeoRaster->nRasterId );
+
+        papszFileList = CSLAddString( papszFileList, osDSName.c_str() );
+    }
+
+    return papszFileList;
+}
+
+//  ---------------------------------------------------------------------------
 //                                                                     Create()
 //  ---------------------------------------------------------------------------
 
@@ -474,7 +938,8 @@ GDALDataset *GeoRasterDataset::Create( const char *pszFilename,
     pszFetched = CSLFetchNameValue( papszOptions, "COMPRESS" );
 
     if( pszFetched != NULL &&
-        ( STARTS_WITH_CI(pszFetched, "JPEG") ||
+        ( EQUAL( pszFetched, "JPEG-F" ) ||
+          EQUAL( pszFetched, "JP2-F" ) ||
           EQUAL( pszFetched, "DEFLATE" ) ) )
     {
         poGRW->sCompressionType = pszFetched;
@@ -529,8 +994,7 @@ GDALDataset *GeoRasterDataset::Create( const char *pszFilename,
     }
     else
     {
-        if( ! EQUAL( poGRW->sCompressionType.c_str(), "NONE" ) &&
-          ( nBands == 3 || nBands == 4 ) )
+        if( nBands == 3 || nBands == 4 )
         {
             poGRW->nBandBlockSize = nBands;
         }
@@ -596,11 +1060,12 @@ GDALDataset *GeoRasterDataset::Create( const char *pszFilename,
         return NULL;
     }
 
-    /* Compression JPEG-B is deprecated. It should be able to read but to
+    /* Compression JPEG-B is deprecated. It should be able to read but not
      * to create new GeoRaster on databases with that compression option.
      *
      * TODO: Remove that options on next release.
      */
+
     if( EQUAL( poGRW->sCompressionType.c_str(), "JPEG-B" ) )
     {
         CPLError( CE_Failure, CPLE_IllegalArg,
@@ -671,6 +1136,16 @@ GDALDataset *GeoRasterDataset::Create( const char *pszFilename,
         }
     }
 
+    // When the compression is JP2-F it should be just one block
+    
+    if( EQUAL( poGRW->sCompressionType.c_str(), "JP2-F" ) )
+    {
+        poGRW->nRowBlockSize    = poGRW->nRasterRows;
+        poGRW->nColumnBlockSize = poGRW->nRasterColumns;
+        poGRW->nBandBlockSize   = poGRW->nRasterBands;
+        poGRW->bBlocking        = false;
+    }
+
     pszFetched = CSLFetchNameValue( papszOptions, "OBJECTTABLE" );
 
     if( pszFetched )
@@ -913,7 +1388,7 @@ GDALDataset *GeoRasterDataset::CreateCopy( const char* pszFilename,
         //  Copy Color Table
         // ----------------------------------------------------------------
 
-        GDALColorTable* poColorTable = poSrcBand->GetColorTable();
+        GDALColorTable* poColorTable = poSrcBand->GetColorTable(); 
 
         if( poColorTable )
         {
@@ -1029,7 +1504,75 @@ GDALDataset *GeoRasterDataset::CreateCopy( const char* pszFilename,
     int nPixelSize = GDALGetDataTypeSize(
         poSrcDS->GetRasterBand(1)->GetRasterDataType() ) / 8;
 
-    if( poDstDS->poGeoRaster->nBandBlockSize == 1)
+    if( EQUAL( poDstDS->poGeoRaster->sCompressionType.c_str(), "JPEG-F" ) &&
+        nBlockXSize == nXSize && nBlockYSize == nYSize ) 
+    {
+        // --------------------------------------------------------------------
+        // Load JPEG avoiding decompression/compression - direct copy
+        // --------------------------------------------------------------------
+        
+        const char* pszDriverName = poSrcDS->GetDriverName();
+
+        if ( EQUAL( pszDriverName, "JPEG" ) )
+        {
+            char** papszFileList = poSrcDS->GetFileList();
+            
+            if ( poDstDS->JPEG_CopyDirect( papszFileList[0],
+                                           pfnProgress,
+                                           pProgressData ) )
+            { 
+                CPLDebug("GEOR","JPEG Direct copy succeed");
+            }            
+        }
+        
+    }
+    else if( EQUAL( poDstDS->poGeoRaster->sCompressionType.c_str(), "JP2-F" ) ) 
+    {
+        // --------------------------------------------------------------------
+        // Load JP2K avoiding decompression/compression - direct copy
+        // --------------------------------------------------------------------
+        
+        boolean bJP2CopyDirectSucceed = false;
+        
+        const char* pszDriverName = poSrcDS->GetDriverName();
+
+        int nJP2Resolution = -1;
+        
+        if ( EQUAL( pszDriverName, "JP2OpenJPEG" ) && 
+             poSrcDS->GetRasterBand(1)->GetColorTable() == NULL )
+        {
+            //  ---------------------------------------------------------------
+            //  Try to load the JP2 file directly
+            //  ---------------------------------------------------------------
+   
+            char** papszFileList = poSrcDS->GetFileList();
+
+            bJP2CopyDirectSucceed = poDstDS->JP2_CopyDirect( papszFileList[0],
+                                                             &nJP2Resolution,
+                                                             pfnProgress,
+                                                             pProgressData );
+
+        }
+
+        if( ! bJP2CopyDirectSucceed )
+        { 
+            //  ---------------------------------------------------------------
+            //  Use VSIOCILOB to load using a resident JP2 driver 
+            //  ---------------------------------------------------------------
+
+            poDstDS->JP2_CreateCopy( poSrcDS,          /* JP2 dataset */
+                                     papszOptions,     /* options list */
+                                     &nJP2Resolution,  /* returned resolution */
+                                     pfnProgress,      /* progress function */
+                                     pProgressData );  /* progress data */
+
+        }
+
+        // Number of pyramid levels is the number of resolutions - 1
+
+        poDstDS->poGeoRaster->SetMaxLevel( MAX( 1, nJP2Resolution - 1 ) );
+    }
+    else if( poDstDS->poGeoRaster->nBandBlockSize == 1)
     {
         // ----------------------------------------------------------------
         //  Band order
@@ -1183,21 +1726,39 @@ CPLErr GeoRasterDataset::IRasterIO( GDALRWFlag eRWFlag,
                                     GDALRasterIOExtraArg* psExtraArg )
 
 {
-    if( poGeoRaster->nBandBlockSize > 1 )
+    if( EQUAL( poGeoRaster->sCompressionType.c_str(), "JP2-F" ) )
     {
-        return GDALDataset::BlockBasedRasterIO( eRWFlag,
-            nXOff, nYOff, nXSize, nYSize,
-            pData, nBufXSize, nBufYSize, eBufType,
-            nBandCount, panBandMap, nPixelSpace,
-            nLineSpace, nBandSpace, psExtraArg );
+        if( poJP2Dataset )
+        {
+            return poJP2Dataset->RasterIO( eRWFlag,
+                        nXOff, nYOff, nXSize, nYSize,
+                        pData, nBufXSize, nBufYSize, eBufType,
+                        nBandCount, panBandMap,
+                        nPixelSpace, nLineSpace, nBandSpace, psExtraArg );
+        }
+        else
+        {
+            return CE_Failure;
+        }
     }
     else
     {
-        return GDALDataset::IRasterIO( eRWFlag,
-            nXOff, nYOff, nXSize, nYSize,
-            pData, nBufXSize, nBufYSize, eBufType,
-            nBandCount, panBandMap,
-            nPixelSpace, nLineSpace, nBandSpace, psExtraArg );
+        if( poGeoRaster->nBandBlockSize > 1 )
+        {
+            return GDALDataset::BlockBasedRasterIO( eRWFlag,
+                        nXOff, nYOff, nXSize, nYSize,
+                        pData, nBufXSize, nBufYSize, eBufType,
+                        nBandCount, panBandMap, nPixelSpace,
+                        nLineSpace, nBandSpace, psExtraArg );
+        }
+        else
+        {
+            return GDALDataset::IRasterIO( eRWFlag,
+                        nXOff, nYOff, nXSize, nYSize,
+                        pData, nBufXSize, nBufYSize, eBufType,
+                        nBandCount, panBandMap,
+                        nPixelSpace, nLineSpace, nBandSpace, psExtraArg );
+        }
     }
 }
 
@@ -1225,7 +1786,7 @@ CPLErr GeoRasterDataset::GetGeoTransform( double *padfTransform )
     {
         return CE_Failure;
     }
-
+    
     memcpy( padfTransform, adfGeoTransform, sizeof(double) * 6 );
 
     bGeoTransform = true;
@@ -1483,11 +2044,11 @@ CPLErr GeoRasterDataset::SetProjection( const char *pszProjString )
     // ----------------------------------------------------------------
 
     OGRSpatialReference *poSRS2 = oSRS.Clone();
-
+    
     poSRS2->StripCTParms();
 
     double dfAngularUnits = poSRS2->GetAngularUnits( NULL );
-
+    
     if( fabs(dfAngularUnits - 0.0174532925199433) < 0.0000000000000010 )
     {
         /* match the precision used on Oracle for that particular value */
@@ -1502,7 +2063,7 @@ CPLErr GeoRasterDataset::SetProjection( const char *pszProjString )
         delete poSRS2;
         return CE_Failure;
     }
-
+    
     const char *pszProjName = poSRS2->GetAttrValue( "PROJECTION" );
 
     if( pszProjName )
@@ -1576,7 +2137,7 @@ CPLErr GeoRasterDataset::SetProjection( const char *pszProjString )
         {
             poSRS2->SetProjection( "Interrupted Goode Homolosine" );
         }
-
+        
         // ----------------------------------------------------------------
         // Translate projection's parameters to Oracle's standards
         // ----------------------------------------------------------------
@@ -1680,12 +2241,12 @@ CPLErr GeoRasterDataset::SetProjection( const char *pszProjString )
     int nNewSRID = 0;
 
     const char *pszFuncName = "FIND_GEOG_CRS";
-
+  
     if( poSRS2->IsProjected() )
     {
         pszFuncName = "FIND_PROJ_CRS";
     }
-
+    
     poStmt = poConnection->CreateStatement( CPLSPrintf(
         "DECLARE\n"
         "  LIST SDO_SRID_LIST;"
@@ -1699,7 +2260,7 @@ CPLErr GeoRasterDataset::SetProjection( const char *pszProjString )
         "END;",
             pszFuncName,
             pszCloneWKT ) );
-
+        
     poStmt->BindName( ":out", &nNewSRID );
 
     CPLPushErrorHandler( CPLQuietErrorHandler );
@@ -1719,14 +2280,14 @@ CPLErr GeoRasterDataset::SetProjection( const char *pszProjString )
     // --------------------------------------------------------------------
     // Search by simplified WKT or insert it as a user defined SRS
     // --------------------------------------------------------------------
-
+    
     int nCounter = 0;
 
     poStmt = poConnection->CreateStatement( CPLSPrintf(
         "SELECT COUNT(*) FROM MDSYS.CS_SRS WHERE WKTEXT = '%s'", pszCloneWKT));
-
+    
     poStmt->Define( &nCounter );
-
+            
     CPLPushErrorHandler( CPLQuietErrorHandler );
 
     if( poStmt->Execute() && nCounter > 0 )
@@ -1739,7 +2300,7 @@ CPLErr GeoRasterDataset::SetProjection( const char *pszProjString )
         if( poStmt->Execute() )
         {
             CPLPopErrorHandler();
-
+            
             poGeoRaster->SetGeoReference( nNewSRID );
             CPLFree( pszCloneWKT );
             return CE_None;
@@ -1747,7 +2308,7 @@ CPLErr GeoRasterDataset::SetProjection( const char *pszProjString )
     }
 
     CPLPopErrorHandler();
-
+    
     poStmt = poConnection->CreateStatement( CPLSPrintf(
         "DECLARE\n"
         "  MAX_SRID NUMBER := 0;\n"
@@ -1770,24 +2331,24 @@ CPLErr GeoRasterDataset::SetProjection( const char *pszProjString )
     if( poStmt->Execute() )
     {
         CPLPopErrorHandler();
-
+            
         poGeoRaster->SetGeoReference( nNewSRID );
     }
     else
     {
         CPLPopErrorHandler();
-
+            
         poGeoRaster->SetGeoReference( UNKNOWN_CRS );
 
         CPLError( CE_Warning, CPLE_UserInterrupt,
             "Insufficient privileges to insert reference system to "
             "table MDSYS.CS_SRS." );
-
+        
         eError = CE_Warning;
     }
 
     CPLFree( pszCloneWKT );
-
+    
     return eError;
 }
 
@@ -1858,7 +2419,7 @@ void GeoRasterDataset::SetSubdatasets( GeoRasterWrapper* poGRW )
         poStmt = poConnection->CreateStatement(
             "SELECT   DISTINCT TABLE_NAME, OWNER FROM ALL_SDO_GEOR_SYSDATA\n"
             "  ORDER  BY TABLE_NAME ASC" );
-
+        
         char szTable[OWNAME];
         char szOwner[OWNAME];
 
@@ -1907,7 +2468,7 @@ void GeoRasterDataset::SetSubdatasets( GeoRasterWrapper* poGRW )
 
         poStmt->Define( szColumn );
         poStmt->Define( szOwner );
-
+        
         if( poStmt->Execute() )
         {
             int nCount = 1;
@@ -1930,7 +2491,7 @@ void GeoRasterDataset::SetSubdatasets( GeoRasterWrapper* poGRW )
             }
             while( poStmt->Fetch() );
         }
-
+        
         return;
     }
 
@@ -2055,6 +2616,11 @@ CPLErr GeoRasterDataset::IBuildOverviews( const char* pszResampling,
     (void) panBandList;
     (void) nListBands;
 
+    if( EQUAL( poGeoRaster->sCompressionType.c_str(), "JP2-F" ) )
+    {
+        return CE_None; // Ignore it, JP2 automatically has overviews
+    }
+
     //  ---------------------------------------------------------------
     //  Can't update on read-only access mode
     //  ---------------------------------------------------------------
@@ -2079,7 +2645,7 @@ CPLErr GeoRasterDataset::IBuildOverviews( const char* pszResampling,
     {
         bInternal = false;
     }
-
+        
     //  -----------------------------------------------------------
     //  Pyramids applies to the whole dataset not to a specific band
     //  -----------------------------------------------------------
@@ -2168,7 +2734,7 @@ CPLErr GeoRasterDataset::IBuildOverviews( const char* pszResampling,
     //  -----------------------------------------------------------
     //  If Pyramid was done internally on the server exit here
     //  -----------------------------------------------------------
-
+    
     if( bInternal )
     {
         pfnProgress( 1 , NULL, pProgressData );
@@ -2258,7 +2824,7 @@ CPLErr GeoRasterDataset::CreateMaskBand( int /*nFlags*/ )
     {
         return CE_Failure;
     }
-
+    
     poGeoRaster->bHasBitmapMask = true;
 
     return CE_None;
@@ -2332,12 +2898,25 @@ void CPL_DLL GDALRegister_GEOR()
 "   </Option>"
 "  <Option name='COMPRESS'    type='string-select'>"
 "       <Value>NONE</Value>"
-"       <Value>JPEG-B</Value>"
 "       <Value>JPEG-F</Value>"
+"       <Value>JP2-F</Value>"
 "       <Value>DEFLATE</Value>"
 "  </Option>"
 "  <Option name='QUALITY'     type='int'    description='JPEG quality 0..100' "
                                            "default='75'/>"
+"  <Option name='JP2_QUALITY'     type='string' description='For JP2-F compression, single quality value or comma separated list "
+        "of increasing quality values for several layers, each in the 0-100 range' default='25'/>"
+"  <Option name='JP2_BLOCKXSIZE'  type='int' description='For JP2 compression, tile Width' default='1024'/>"
+"  <Option name='JP2_BLOCKYSIZE'  type='int' description='For JP2 compression, tile Height' default='1024'/>"
+"  <Option name='JP2_REVERSIBLE'  type='boolean' description='For JP2-F compression, True if the compression is reversible' default='false'/>"
+"  <Option name='JP2_RESOLUTIONS' type='int' description='For JP2-F compression, Number of resolutions.' min='1' max='30'/>"
+"  <Option name='JP2_PROGRESSION' type='string-select' description='For JP2-F compression, progression order' default='LRCP'>"
+"    <Value>LRCP</Value>"
+"    <Value>RLCP</Value>"
+"    <Value>RPCL</Value>"
+"    <Value>PCRL</Value>"
+"    <Value>CPRL</Value>"
+"  </Option>"
 "</CreationOptionList>" );
 
     poDriver->pfnOpen       = GeoRasterDataset::Open;
@@ -2347,4 +2926,6 @@ void CPL_DLL GDALRegister_GEOR()
     poDriver->pfnDelete     = GeoRasterDataset::Delete;
 
     GetGDALDriverManager()->RegisterDriver( poDriver );
+
+    VSIInstallOCILobHandler();
 }
diff --git a/frmts/georaster/georaster_priv.h b/frmts/georaster/georaster_priv.h
index 5dfca52..eaa17cf 100644
--- a/frmts/georaster/georaster_priv.h
+++ b/frmts/georaster/georaster_priv.h
@@ -1,5 +1,4 @@
 /******************************************************************************
- * $Id: georaster_priv.h 36501 2016-11-25 14:09:24Z rouault $
  *
  * Name:     georaster_priv.h
  * Project:  Oracle Spatial GeoRaster Driver
@@ -57,6 +56,14 @@ void jpeg_vsiio_src (j_decompress_ptr cinfo, VSILFILE * infile);
 void jpeg_vsiio_dest (j_compress_ptr cinfo, VSILFILE * outfile);
 
 //  ---------------------------------------------------------------------------
+//  JPEG2000 support - Install the Vitual File System handler to OCI LOB
+//  ---------------------------------------------------------------------------
+
+CPL_C_START
+void CPL_DLL VSIInstallOCILobHandler(void);
+CPL_C_END
+
+//  ---------------------------------------------------------------------------
 //  System constants
 //  ---------------------------------------------------------------------------
 
@@ -76,8 +83,8 @@ void jpeg_vsiio_dest (j_compress_ptr cinfo, VSILFILE * outfile);
 
 //  Default block size
 
-#define DEFAULT_BLOCK_ROWS 256
-#define DEFAULT_BLOCK_COLUMNS 256
+#define DEFAULT_BLOCK_ROWS 512
+#define DEFAULT_BLOCK_COLUMNS 512
 
 //  Default Model Coordinate Location (internal pixel geo-reference)
 
@@ -89,6 +96,8 @@ void jpeg_vsiio_dest (j_compress_ptr cinfo, VSILFILE * outfile);
 
 #define MAX_DOUBLE_STR_REP 20
 
+// Pyramid levels details
+
 struct hLevelDetails {
     int             nColumnBlockSize;
     int             nRowBlockSize;
@@ -145,9 +154,24 @@ private:
     GeoRasterRasterBand*
                         poMaskBand;
     bool                bApplyNoDataArray;
+    void                JP2_Open( GDALAccess eAccess );
+    void                JP2_CreateCopy( GDALDataset* poJP2DS,
+                                        char** papszOptions,
+                                        int* pnResolutions,
+                                        GDALProgressFunc pfnProgress,
+                                        void* pProgressData );
+    boolean             JP2_CopyDirect( const char* pszJP2Filename,
+                                        int* pnResolutions,
+                                        GDALProgressFunc pfnProgress,
+                                        void* pProgressData );
+    boolean             JPEG_CopyDirect( const char* pszJPGFilename,
+                                         GDALProgressFunc pfnProgress,
+                                         void* pProgressData );
 
 public:
 
+    GDALDataset*        poJP2Dataset;
+
     void                SetSubdatasets( GeoRasterWrapper* poGRW );
 
     static int          Identify( GDALOpenInfo* poOpenInfo );
@@ -200,6 +224,8 @@ public:
     virtual OGRErr      StartTransaction(int /* bForce */ =FALSE) override {return CE_None;};
     virtual OGRErr      CommitTransaction() override {return CE_None;};
     virtual OGRErr      RollbackTransaction() override {return CE_None;};
+    
+    virtual char**      GetFileList() override;
 
     void                AssignGeoRaster( GeoRasterWrapper* poGRW );
 };
@@ -215,7 +241,8 @@ class GeoRasterRasterBand : public GDALRasterBand
 public:
                         GeoRasterRasterBand( GeoRasterDataset* poGDS,
                             int nBand,
-                            int nLevel );
+                            int nLevel,
+                            GDALDataset* poJP2Dataset = NULL );
     virtual            ~GeoRasterRasterBand();
 
 private:
@@ -224,6 +251,7 @@ private:
     GDALColorTable*     poColorTable;
     GDALRasterAttributeTable*
                         poDefaultRAT;
+    GDALDataset*        poJP2Dataset;
     double              dfMin;
     double              dfMax;
     double              dfMean;
@@ -294,6 +322,7 @@ private:
     GByte*              pabyBlockBuf;
     GByte*              pabyCompressBuf;
     OWStatement*        poBlockStmt;
+    OWStatement*        poStmtWrite;
 
     int                 nCurrentLevel;
     long                nLevelOffset;
@@ -407,6 +436,7 @@ public:
                                                 int nBandBlocks );
     void                SetWriteOnly( bool value ) { bWriteOnly = value; };
     void                SetRPC();
+    void                SetMaxLevel( int nMaxLevel );
     void                GetRPC();
 
 public:
@@ -436,7 +466,7 @@ public:
     CPLString           sCompressionType;
     int                 nCompressQuality;
     CPLString           sWKText;
-
+    CPLString           sAuthority;
     CPLList*            psNoDataList;
 
     int                 nRasterColumns;
diff --git a/frmts/georaster/georaster_rasterband.cpp b/frmts/georaster/georaster_rasterband.cpp
index 349c0bf..14478a1 100644
--- a/frmts/georaster/georaster_rasterband.cpp
+++ b/frmts/georaster/georaster_rasterband.cpp
@@ -35,7 +35,7 @@
 #include "cpl_vsi.h"
 #include "cpl_error.h"
 
-CPL_CVSID("$Id: georaster_rasterband.cpp 34811 2016-07-28 15:15:05Z goatbar $");
+CPL_CVSID("$Id: georaster_rasterband.cpp 38020 2017-04-14 21:40:01Z rouault $");
 
 //  ---------------------------------------------------------------------------
 //                                                        GeoRasterRasterBand()
@@ -43,7 +43,8 @@ CPL_CVSID("$Id: georaster_rasterband.cpp 34811 2016-07-28 15:15:05Z goatbar $");
 
 GeoRasterRasterBand::GeoRasterRasterBand( GeoRasterDataset *poGDS,
                                           int nBandIn,
-                                          int nLevel )
+                                          int nLevel,
+                                          GDALDataset* poJP2DatasetIn )
 {
     poDS                = (GDALDataset*) poGDS;
     poGeoRaster         = poGDS->poGeoRaster;
@@ -64,6 +65,8 @@ GeoRasterRasterBand::GeoRasterRasterBand( GeoRasterDataset *poGDS,
     pahNoDataArray      = NULL;
     nNoDataArraySz      = 0;
     bHasNoDataArray     = false;
+   
+    poJP2Dataset        = poJP2DatasetIn;
 
     //  -----------------------------------------------------------------------
     //  Initialize overview list
@@ -77,7 +80,7 @@ GeoRasterRasterBand::GeoRasterRasterBand( GeoRasterDataset *poGDS,
         for( int i = 0; i < nOverviewCount; i++ )
         {
           papoOverviews[i] = new GeoRasterRasterBand(
-                (GeoRasterDataset*) poDS, nBand, i + 1 );
+                (GeoRasterDataset*) poDS, nBand, i + 1, poJP2Dataset );
         }
     }
 
@@ -166,6 +169,7 @@ GeoRasterRasterBand::GeoRasterRasterBand( GeoRasterDataset *poGDS,
                      * Use the first value to assigned pixel values
                      * on method ApplyNoDataArray()
                      */
+                    
                     dfNoData = phItem->dfLower;
                 }
             }
@@ -183,7 +187,7 @@ GeoRasterRasterBand::~GeoRasterRasterBand()
 {
     delete poColorTable;
     delete poDefaultRAT;
-
+    
     CPLFree( pszVATName );
     CPLFree( pahNoDataArray );
 
@@ -206,6 +210,21 @@ CPLErr GeoRasterRasterBand::IReadBlock( int nBlockXOff,
                                         int nBlockYOff,
                                         void *pImage )
 {
+    if( poJP2Dataset )
+    {
+        int nXOff      = nBlockXOff * poGeoRaster->nColumnBlockSize;
+        int nYOff      = nBlockYOff * poGeoRaster->nRowBlockSize;
+        int nXSize     = poGeoRaster->nColumnBlockSize;
+        int nYSize     = poGeoRaster->nRowBlockSize;
+        int nBufXSize  = nBlockXSize;
+        int nBufYSize  = nBlockYSize;
+
+        return GDALDatasetRasterIO( poJP2Dataset, GF_Read,
+                    nXOff, nYOff, nXSize, nYSize, pImage, 
+                    nBufXSize, nBufYSize, eDataType,
+                    1, &nBand, 0, 0, 0 );
+    }
+
     if( poGeoRaster->GetDataBlock( nBand,
                                    nOverviewLevel,
                                    nBlockXOff,
@@ -237,6 +256,21 @@ CPLErr GeoRasterRasterBand::IWriteBlock( int nBlockXOff,
                                          int nBlockYOff,
                                          void *pImage )
 {
+    if( poJP2Dataset )
+    {
+        int nXOff      = nBlockXOff * poGeoRaster->nColumnBlockSize;
+        int nYOff      = nBlockYOff * poGeoRaster->nRowBlockSize;
+        int nXSize     = poGeoRaster->nColumnBlockSize;
+        int nYSize     = poGeoRaster->nRowBlockSize;
+        int nBufXSize  = nBlockXSize;
+        int nBufYSize  = nBlockYSize;
+
+        return GDALDatasetRasterIO( poJP2Dataset, GF_Write,
+                    nXOff, nYOff, nXSize, nYSize, pImage, 
+                    nBufXSize, nBufYSize, eDataType,
+                    1, &nBand, 0, 0, 0 );
+    }
+
     if( poGeoRaster->SetDataBlock( nBand,
                                    nOverviewLevel,
                                    nBlockXOff,
@@ -642,7 +676,7 @@ CPLErr GeoRasterRasterBand::SetDefaultRAT( const GDALRasterAttributeTable *poRAT
                  (void*) VSIMalloc3(sizeof(double), sizeof(double), nEntryCount );
         }
     }
-
+    
     // ---------------------------
     // Load data to buffers
     // ---------------------------
@@ -682,7 +716,7 @@ CPLErr GeoRasterRasterBand::SetDefaultRAT( const GDALRasterAttributeTable *poRAT
     // ---------------------------
 
     CPLString osInsert = CPLSPrintf( "INSERT INTO %s VALUES (", pszVATName );
-
+    
     for( iCol = 0; iCol < ( nColunsCount + 1); iCol++ )
     {
         if( iCol > 0 )
@@ -700,7 +734,7 @@ CPLErr GeoRasterRasterBand::SetDefaultRAT( const GDALRasterAttributeTable *poRAT
     // ---------------------------
 
     poStmt->Bind((int*) papWriteFields[0]); // ID field
-
+    
     for(iCol = 0; iCol < nColunsCount; iCol++)
     {
         if( poRAT->GetTypeOfCol( iCol ) == GFT_String )
@@ -734,7 +768,7 @@ CPLErr GeoRasterRasterBand::SetDefaultRAT( const GDALRasterAttributeTable *poRAT
     {
         CPLFree( papWriteFields[iCol] );
     }
-
+    
     CPLFree( papWriteFields );
 
     delete poStmt;
diff --git a/frmts/georaster/georaster_wrapper.cpp b/frmts/georaster/georaster_wrapper.cpp
index 6c66e5e..2b34879 100644
--- a/frmts/georaster/georaster_wrapper.cpp
+++ b/frmts/georaster/georaster_wrapper.cpp
@@ -34,7 +34,7 @@
 #include "cpl_string.h"
 #include "cpl_minixml.h"
 
-CPL_CVSID("$Id: georaster_wrapper.cpp 36367 2016-11-21 01:25:12Z rouault $");
+CPL_CVSID("$Id: georaster_wrapper.cpp 38020 2017-04-14 21:40:01Z rouault $");
 
 //  ---------------------------------------------------------------------------
 //                                                           GeoRasterWrapper()
@@ -72,6 +72,7 @@ GeoRasterWrapper::GeoRasterWrapper() :
     pabyCompressBuf     = NULL;
     bIsReferenced       = false;
     poBlockStmt         = NULL;
+    poStmtWrite         = NULL;
     nCacheBlockId       = -1;
     nCurrentLevel       = -1;
     pahLevels           = NULL;
@@ -240,11 +241,36 @@ GeoRasterWrapper* GeoRasterWrapper::Open( const char* pszStringId, bool bUpdate
     //  Get a connection with Oracle server
     //  ---------------------------------------------------------------
 
-    poGRW->poConnection = new OWConnection( papszParam[0],
-                                            papszParam[1],
-                                            papszParam[2] );
+    if( strlen( papszParam[0] ) == 0 &&
+        strlen( papszParam[1] ) == 0 &&
+        strlen( papszParam[2] ) == 0 )
+    {
+        /* In an external procedure environment, before openning any
+         * dataset, the caller must pass the with_context as an
+         * string metadata item OCI_CONTEXT_PTR to the driver. */ 
+
+        const char*        pszContext   = NULL;
+        OCIExtProcContext* with_context = NULL;
 
-    if( ! poGRW->poConnection->Succeeded() )
+        pszContext = GDALGetMetadataItem( GDALGetDriverByName("GEORASTER"), 
+                                          "OCI_CONTEXT_PTR", NULL );
+
+        if( pszContext )
+        {
+            sscanf( pszContext, "%p", &with_context );
+
+            poGRW->poConnection = new OWConnection( with_context );
+        }
+    }
+    else
+    {
+        poGRW->poConnection = new OWConnection( papszParam[0],
+                                                papszParam[1],
+                                                papszParam[2] );
+    }
+
+    if( ! poGRW->poConnection || 
+        ! poGRW->poConnection->Succeeded() )
     {
         CSLDestroy( papszParam );
         delete poGRW;
@@ -255,7 +281,12 @@ GeoRasterWrapper* GeoRasterWrapper::Open( const char* pszStringId, bool bUpdate
     //  Extract schema name
     //  -------------------------------------------------------------------
 
-    if( nArgc > 3 )
+    if( poGRW->poConnection->IsExtProc() )
+    {
+        poGRW->sOwner  = poGRW->poConnection->GetExtProcUser();
+        poGRW->sSchema = poGRW->poConnection->GetExtProcSchema();
+    }
+    else
     {
         char** papszSchema = CSLTokenizeString2( papszParam[3], ".",
                                 CSLT_HONOURSTRINGS | CSLT_ALLOWEMPTYTOKENS );
@@ -282,11 +313,6 @@ GeoRasterWrapper* GeoRasterWrapper::Open( const char* pszStringId, bool bUpdate
 
         CSLDestroy( papszSchema );
     }
-    else
-    {
-        poGRW->sSchema = "";
-        poGRW->sOwner  = poGRW->poConnection->GetUser();
-    }
 
     //  -------------------------------------------------------------------
     //  Assign parameters from Identification string
@@ -371,7 +397,7 @@ GeoRasterWrapper* GeoRasterWrapper::Open( const char* pszStringId, bool bUpdate
       "  SCM VARCHAR2(64) := 'xmlns=\"http://xmlns.oracle.com/spatial/georaster\"';\n"
       "BEGIN\n"
       "\n"
-      "    IF :datatable IS NOT NULL AND :rasterid  > 0 THEN\n"
+      "    IF :datatable IS NOT NULL AND :rasterid  IS NOT NULL THEN\n"
       "\n"
       "      EXECUTE IMMEDIATE\n"
       "        'SELECT OWNER, TABLE_NAME, COLUMN_NAME\n"
@@ -738,7 +764,7 @@ bool GeoRasterWrapper::Create( char* pszDescription,
     //  Create Georaster Table if needed
     //  -------------------------------------------------------------------
 
-    OWStatement* poStmt = NULL;
+    OWStatement* poStmt;
 
     if( ! bUpdateIn )
     {
@@ -890,8 +916,6 @@ bool GeoRasterWrapper::Create( char* pszDescription,
             "      INTO  :metadata\n"
             "     USING  :rdt, :rid;\n"
             "\n"
-            "  COMMIT;\n"
-            "\n"
             "END;\n",
                 sTable.c_str(),
                 sColumn.c_str(),
@@ -1026,8 +1050,6 @@ bool GeoRasterWrapper::Create( char* pszDescription,
         " T.%s.RasterDataTable = :rdt AND"
         " T.%s.RasterId = :rid;\n"
         "\n"
-        "  COMMIT;\n"
-        "\n"
         "END;",
             sOwner.c_str(),
             sCommand.c_str(),
@@ -1649,8 +1671,8 @@ bool GeoRasterWrapper::InitializeIO( void )
     {
         int nRBS = nRowBlockSize;
         int nCBS = nColumnBlockSize;
-        int nTCB;
-        int nTRB;
+        int nTCB = nTotalColumnBlocks;
+        int nTRB = nTotalRowBlocks;
 
         // --------------------------------------------------------------------
         // Calculate the actual size of a lower resolution block
@@ -2241,15 +2263,15 @@ void GeoRasterWrapper::GetSpatialReference()
     int i;
 
     CPLXMLNode* phSRSInfo = CPLGetXMLNode( phMetadata, "spatialReferenceInfo" );
-
+    
     if( phSRSInfo == NULL )
     {
         return;
     }
-
-    const char* pszMCL = CPLGetXMLValue( phSRSInfo, "modelCoordinateLocation",
+    
+    const char* pszMCL = CPLGetXMLValue( phSRSInfo, "modelCoordinateLocation", 
                                                     "CENTER" );
-
+    
     if( EQUAL( pszMCL, "CENTER" ) )
     {
       eModelCoordLocation = MCL_CENTER;
@@ -2260,7 +2282,7 @@ void GeoRasterWrapper::GetSpatialReference()
     }
 
     const char* pszModelType = CPLGetXMLValue( phSRSInfo, "modelType", "None" );
-
+    
     if( EQUAL( pszModelType, "FunctionalFitting" ) == false )
     {
         return;
@@ -2282,7 +2304,7 @@ void GeoRasterWrapper::GetSpatialReference()
 
     int nNumCoeff = atoi( CPLGetXMLValue( phPolynomial, "nCoefficients", "0" ));
 
-    if ( nNumCoeff != 3 )
+    if ( nNumCoeff != 3 ) 
     {
         return;
     }
@@ -2295,8 +2317,8 @@ void GeoRasterWrapper::GetSpatialReference()
         return;
     }
 
-    char** papszCeoff = CSLTokenizeString2( pszPolyCoeff, " ",
-                                            CSLT_STRIPLEADSPACES );
+    char** papszCeoff = CSLTokenizeString2( pszPolyCoeff, " ", 
+                                           CSLT_STRIPLEADSPACES );
 
     if( CSLCount( papszCeoff ) < 3 )
     {
@@ -2304,7 +2326,7 @@ void GeoRasterWrapper::GetSpatialReference()
     }
 
     double adfPCoef[3];
-
+    
     for( i = 0; i < 3; i++ )
     {
         adfPCoef[i] = CPLAtof( papszCeoff[i] );
@@ -2330,7 +2352,7 @@ void GeoRasterWrapper::GetSpatialReference()
     {
         return;
     }
-
+    
     double adfRCoef[3];
 
     for( i = 0; i < 3; i++ )
@@ -2345,7 +2367,7 @@ void GeoRasterWrapper::GetSpatialReference()
     double adfVal[6] = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
 
     double dfDet = adfRCoef[1] * adfPCoef[2] - adfRCoef[2] * adfPCoef[1];
-
+   
     if( CPLIsEqual( dfDet, 0.0 ) )
     {
         dfDet = 0.0000000001; // to avoid divide by zero
@@ -2362,26 +2384,14 @@ void GeoRasterWrapper::GetSpatialReference()
     //  -------------------------------------------------------------------
     //  Adjust Model Coordinate Location
     //  -------------------------------------------------------------------
-
-    if ( eModelCoordLocation == MCL_CENTER )
-    {
-        adfVal[2] -= adfVal[0] / 2.0;
-        adfVal[5] -= adfVal[4] / 2.0;
-    }
-/*
-    CPLDebug("GEOR", "m = [%g, %g, %g, %g, %g, %g]", adfRCoef[1], adfRCoef[2],
-             adfRCoef[0], adfPCoef[1], adfPCoef[2], adfPCoef[0]);
-
-    CPLDebug("GEOR", "i = [%g, %g, %g, %g, %g, %g]", adfVal[0], adfVal[1],
-             adfVal[2], adfVal[3], adfVal[4], adfVal[5]);
-*/
+    
     dfXCoefficient[0] = adfVal[0];
     dfXCoefficient[1] = adfVal[1];
     dfXCoefficient[2] = adfVal[2];
     dfYCoefficient[0] = adfVal[3];
     dfYCoefficient[1] = adfVal[4];
     dfYCoefficient[2] = adfVal[5];
-
+    
     //  -------------------------------------------------------------------
     //  Apply ULTCoordinate
     //  -------------------------------------------------------------------
@@ -2761,6 +2771,21 @@ void GeoRasterWrapper::SetRPC()
 }
 
 //  ---------------------------------------------------------------------------
+//                                                                 SetMaxLeve()
+//  ---------------------------------------------------------------------------
+
+void GeoRasterWrapper::SetMaxLevel( int nLevels )
+{
+    CPLXMLNode* psNode = CPLGetXMLNode( phMetadata, "rasterInfo.pyramid" );
+
+    if( psNode )
+    {
+        CPLSetXMLValue( psNode, "type", "DECREASE" );
+        CPLSetXMLValue( psNode, "maxLevel", CPLSPrintf( "%d", nLevels ) );
+    }
+}
+
+//  ---------------------------------------------------------------------------
 //                                                                  GetNoData()
 //  ---------------------------------------------------------------------------
 
@@ -2917,8 +2942,6 @@ bool GeoRasterWrapper::SetNoData( int nLayer, const char* pszValue )
         "     WHERE  T.%s.RASTERDATATABLE = UPPER(:1)\n"
         "       AND  T.%s.RASTERID = :2'\n"
         "    INTO :metadata USING :rdt, :rid;\n"
-        "\n"
-        "  COMMIT;\n"
         "END;",
             sColumn.c_str(), sSchema.c_str(), sTable.c_str(), sWhere.c_str(),
             sSchema.c_str(), sTable.c_str(), sColumn.c_str(), sWhere.c_str(),
diff --git a/frmts/georaster/makefile.vc b/frmts/georaster/makefile.vc
index 3694b84..b081175 100644
--- a/frmts/georaster/makefile.vc
+++ b/frmts/georaster/makefile.vc
@@ -5,7 +5,8 @@ GDAL_ROOT = ..\..
 OBJ = oci_wrapper.obj \
       georaster_dataset.obj \
       georaster_rasterband.obj \
-      georaster_wrapper.obj
+      georaster_wrapper.obj \
+      cpl_vsil_ocilob.obj
 
 PLUGIN_DLL = gdal_GEOR.dll
 
diff --git a/frmts/georaster/oci_wrapper.cpp b/frmts/georaster/oci_wrapper.cpp
index 9f64ff8..3bfddb2 100644
--- a/frmts/georaster/oci_wrapper.cpp
+++ b/frmts/georaster/oci_wrapper.cpp
@@ -29,7 +29,7 @@
 
 #include "oci_wrapper.h"
 
-CPL_CVSID("$Id: oci_wrapper.cpp 36347 2016-11-20 20:43:39Z rouault $");
+CPL_CVSID("$Id: oci_wrapper.cpp 38020 2017-04-14 21:40:01Z rouault $");
 
 static const OW_CellDepth ahOW_CellDepth[] = {
     {"8BIT_U",          GDT_Byte},
@@ -50,6 +50,76 @@ static const OW_CellDepth ahOW_CellDepth[] = {
 /*                            OWConnection                                   */
 /*****************************************************************************/
 
+OWConnection::OWConnection( OCIExtProcContext* poWithContext )
+{
+    pszUser         = CPLStrdup( "" );
+    pszPassword     = CPLStrdup( "" );
+    pszServer       = CPLStrdup( "" );
+
+    hEnv            = NULL;
+    hError          = NULL;
+    hSvcCtx         = NULL;
+    hSession        = NULL;
+    hDescribe       = NULL;
+    hNumArrayTDO    = NULL;
+    hGeometryTDO    = NULL;
+    hGeoRasterTDO   = NULL;
+    hElemArrayTDO   = NULL;
+    hOrdnArrayTDO   = NULL;
+    bSuceeeded      = false;
+    nCharSize       = 1;
+    bExtProc        = false;
+
+    if( ! poWithContext )
+    {
+       return;
+    }
+
+    // ------------------------------------------------------
+    //  Retrieve connection handlers
+    // ------------------------------------------------------
+
+    if( CheckError( OCIExtProcGetEnv( poWithContext,
+        &hEnv, 
+        &hSvcCtx, 
+        &hError ), NULL ) )
+    {
+       return;
+    }
+
+    //  -------------------------------------------------------------------
+    //  Get User Name and Schema from SYS_CONTEXT on EXTPROC
+    //  -------------------------------------------------------------------
+
+    char szUser[OWTEXT];
+    char szSchema[OWTEXT];
+
+    szUser[0]   = '\0';
+    szSchema[0] = '\0';
+
+    OWStatement* poStmt = CreateStatement(
+            "select sys_context('userenv','current_user'),\n"
+            "       sys_context('userenv','current_schema') || '.'\n"
+            "from dual\n" );
+
+    poStmt->Define(szUser);
+    poStmt->Define(szSchema);
+
+    poStmt->Execute();
+
+    pszExtProcSchema = CPLStrdup( szSchema );
+    pszExtProcUser   = CPLStrdup( szUser );
+
+    CPLDebug("GEOR","User from sys_context = %s", pszExtProcUser);
+
+    delete poStmt;
+
+    QueryVersion();
+
+    bSuceeeded      = true;
+    bExtProc        = true;
+}
+
 OWConnection::OWConnection( const char* pszUserIn,
                             const char* pszPasswordIn,
                             const char* pszServerIn )
@@ -57,9 +127,11 @@ OWConnection::OWConnection( const char* pszUserIn,
     pszUser         = CPLStrdup( pszUserIn );
     pszPassword     = CPLStrdup( pszPasswordIn );
     pszServer       = CPLStrdup( pszServerIn );
+
     hEnv            = NULL;
     hError          = NULL;
     hSvcCtx         = NULL;
+    hSession        = NULL;
     hDescribe       = NULL;
     hNumArrayTDO    = NULL;
     hGeometryTDO    = NULL;
@@ -68,6 +140,7 @@ OWConnection::OWConnection( const char* pszUserIn,
     hOrdnArrayTDO   = NULL;
     bSuceeeded      = false;
     nCharSize       = 1;
+    bExtProc        = false;
 
     // ------------------------------------------------------
     //  Operational Systems's authentication option
@@ -132,7 +205,7 @@ OWConnection::OWConnection( const char* pszUserIn,
         return;
     }
 
-    if( CheckError( OCIHandleAlloc((dvoid *) hEnv, (dvoid **)&hSession,
+    if( CheckError( OCIHandleAlloc((dvoid *) hEnv, (dvoid **) &hSession,
         (ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0), hError ) )
     {
         return;
@@ -149,7 +222,7 @@ OWConnection::OWConnection( const char* pszUserIn,
     }
 
     if( CheckError( OCIAttrSet((dvoid *) hSession, (ub4) OCI_HTYPE_SESSION,
-        (dvoid *) pszUserId, (ub4) strlen( pszUserId),
+        (dvoid *) pszUserId, (ub4) strlen((char*) pszUserId),
         (ub4) OCI_ATTR_USERNAME, hError), hError ) )
     {
         return;
@@ -162,7 +235,7 @@ OWConnection::OWConnection( const char* pszUserIn,
         return;
     }
 
-    if( CheckError( OCIAttrSet( (dvoid *) hSvcCtx, OCI_HTYPE_SVCCTX, (dvoid *)hServer,
+    if( CheckError( OCIAttrSet( (dvoid *) hSvcCtx, OCI_HTYPE_SVCCTX, (dvoid *) hServer,
         (ub4) 0, OCI_ATTR_SERVER, (OCIError *) hError), hError ) )
     {
         return;
@@ -189,9 +262,36 @@ OWConnection::OWConnection( const char* pszUserIn,
         return;
     }
 
+    QueryVersion();
+
     bSuceeeded = true;
 
     // ------------------------------------------------------
+    //  Initialize/Describe types
+    // ------------------------------------------------------
+
+    CheckError( OCIHandleAlloc(
+        (dvoid*) hEnv,
+        (dvoid**) (dvoid*) &hDescribe,
+        (ub4) OCI_HTYPE_DESCRIBE,
+        (size_t) 0,
+        (dvoid**) NULL ), hError );
+
+    hNumArrayTDO    = DescribeType( SDO_NUMBER_ARRAY );
+    hGeometryTDO    = DescribeType( SDO_GEOMETRY );
+    hGeoRasterTDO   = DescribeType( SDO_GEORASTER );
+    hElemArrayTDO   = DescribeType( SDO_ELEM_INFO_ARRAY);
+    hOrdnArrayTDO   = DescribeType( SDO_ORDINATE_ARRAY);
+
+    if( nVersion > 10 )
+    {
+        hPCTDO      = DescribeType( SDO_PC );
+    }
+}
+
+void OWConnection::QueryVersion()
+{
+    // ------------------------------------------------------
     //  Get Character Size based on current Locale
     // ------------------------------------------------------
 
@@ -212,51 +312,64 @@ OWConnection::OWConnection( const char* pszUserIn,
         (ub1) OCI_HTYPE_SVCCTX );
 
     nVersion = OWParseServerVersion( szVersionTxt );
+}
 
-    // ------------------------------------------------------
-    //  Initialize/Describe types
-    // ------------------------------------------------------
+OWConnection::~OWConnection()
+{
+    CPLFree( pszUser );
+    CPLFree( pszPassword );
+    CPLFree( pszServer );
 
-    CheckError( OCIHandleAlloc(
-        (dvoid*) hEnv,
-        (dvoid**) (dvoid*) &hDescribe,
-        (ub4) OCI_HTYPE_DESCRIBE,
-        (size_t) 0,
-        (dvoid**) NULL ), hError );
+    DestroyType( hNumArrayTDO );
+    DestroyType( hGeometryTDO );
+    DestroyType( hGeoRasterTDO );
+    DestroyType( hElemArrayTDO );
+    DestroyType( hOrdnArrayTDO );
 
-    hNumArrayTDO    = DescribeType( SDO_NUMBER_ARRAY );
-    hGeometryTDO    = DescribeType( SDO_GEOMETRY );
-    hGeoRasterTDO   = DescribeType( SDO_GEORASTER );
-    hElemArrayTDO   = DescribeType( SDO_ELEM_INFO_ARRAY);
-    hOrdnArrayTDO   = DescribeType( SDO_ORDINATE_ARRAY);
+    OCIHandleFree( (dvoid*) hDescribe, (ub4) OCI_HTYPE_DESCRIBE);
 
-    if( nVersion > 10 )
+    // ------------------------------------------------------
+    //  Do not free OCI handles from a external procedure
+    // ------------------------------------------------------
+
+    if( bExtProc )
     {
-        hPCTDO      = DescribeType( SDO_PC );
+        return;
     }
-}
 
-OWConnection::~OWConnection()
-{
-    OCIHandleFree( (dvoid*) hDescribe, (ub4) OCI_HTYPE_DESCRIBE);
+    // ------------------------------------------------------
+    //  Terminate session and free OCI handles
+    // ------------------------------------------------------
 
     if( hSvcCtx && hError && hSession )
+    {
         OCISessionEnd( hSvcCtx, hError, hSession, (ub4) 0);
+    }
 
     if( hSvcCtx && hError)
+    {
         OCIServerDetach( hServer, hError, (ub4) OCI_DEFAULT);
+    }
 
     if( hServer )
+    {
         OCIHandleFree((dvoid *) hServer, (ub4) OCI_HTYPE_SERVER);
+    }
 
     if( hSvcCtx )
+    {
         OCIHandleFree((dvoid *) hSvcCtx, (ub4) OCI_HTYPE_SVCCTX);
+    }
 
     if( hError )
+    {
         OCIHandleFree((dvoid *) hError, (ub4) OCI_HTYPE_ERROR);
+    }
 
     if( hSession )
+    {
         OCIHandleFree((dvoid *) hSession, (ub4) OCI_HTYPE_SESSION);
+    }
 }
 
 OCIType* OWConnection::DescribeType( const char *pszTypeName )
@@ -300,7 +413,23 @@ OCIType* OWConnection::DescribeType( const char *pszTypeName )
         (OCIDuration) OCI_DURATION_SESSION,
         (OCILockOpt) OCI_LOCK_NONE,
         (dvoid**) (dvoid*) &hType ), hError );
+/*
+    OCIType*  hType     = NULL;
 
+    CheckError( OCITypeByName(
+        hEnv,
+        hError,
+        hSvcCtx,
+        (text*) TYPE_OWNER,
+        (ub4) strlen(TYPE_OWNER),
+        (text*) pszTypeName,
+        (ub4) strlen(pszTypeName),
+        (text*) 0, 
+        (ub4) 0, 
+        OCI_DURATION_SESSION,
+        OCI_TYPEGET_HEADER, 
+        &hType), hError );
+*/
     return hType;
 }
 
@@ -318,6 +447,19 @@ void OWConnection::CreateType( sdo_geometry** pphData )
         (dvoid **) pphData), hError );
 }
 
+void OWConnection::DestroyType( OCIType* phType )
+{
+    if( phType == NULL )
+    {
+        return;
+    }
+
+    CheckError( OCIObjectUnpin(
+        hEnv,
+        hError,
+        (dvoid*) phType ), hError );
+}
+
 void OWConnection::DestroyType( sdo_geometry** pphData )
 {
     CheckError( OCIObjectFree(
@@ -741,11 +883,12 @@ void OWStatement::Bind( sdo_geometry** pphData )
         hBind,
         hError,
         poConnection->hGeometryTDO,
-    (dvoid**) pphData,
+        (dvoid**) pphData,
         (ub4*) 0,
-    (dvoid**) 0,
+        (dvoid**) 0,
         (ub4*) 0),
         hError );
+
 }
 
 void OWStatement::Bind( OCILobLocator** pphLocator )
@@ -1267,6 +1410,22 @@ void OWStatement::AddElement( OCIArray* poData,
         (OCIColl*) poData), hError);
 }
 
+unsigned long OWStatement::GetBlobLength( OCILobLocator* phLocator )
+{
+    ub8 nSize      = (ub8) 0;
+
+    if( CheckError( OCILobGetLength2(
+        poConnection->hSvcCtx,
+        poConnection->hError,
+        phLocator,
+        (ub8*) &nSize), hError ) )
+    {
+        return 0;
+    }
+
+    return nSize;
+}
+                                         
 unsigned long OWStatement::ReadBlob( OCILobLocator* phLocator,
                                      void* pBuffer,
                                      int nSize )
@@ -1292,6 +1451,34 @@ unsigned long OWStatement::ReadBlob( OCILobLocator* phLocator,
     return nAmont;
 }
 
+unsigned long OWStatement::ReadBlob( OCILobLocator* phLocator,
+                                     void* pBuffer,
+                                     int nOffset,
+                                     int nSize )
+{
+    ub8 nAmont = (ub8) nSize;
+
+    if( CheckError( OCILobRead2(
+        poConnection->hSvcCtx,
+        hError,
+        phLocator,
+        (ub8*) &nAmont,
+        (ub8*) NULL,
+        (ub8) nOffset,
+        (dvoid*) pBuffer,
+        (ub8) nSize,
+        (ub1) OCI_ONE_PIECE,
+        (dvoid *) 0,
+        (OCICallbackLobRead2) 0,
+        (ub2) 0,
+        (ub1) SQLCS_IMPLICIT), hError ) )
+    {
+        return 0;
+    }
+
+    return nAmont;
+}
+
 bool OWStatement::WriteBlob( OCILobLocator* phLocator,
                              void* pBuffer,
                              int nSize )
@@ -1319,6 +1506,33 @@ bool OWStatement::WriteBlob( OCILobLocator* phLocator,
     return nAmont == (ub4) nSize;
 }
 
+int OWStatement::WriteBlob( OCILobLocator* phLocator,
+                             void* pBuffer,
+                             int nOffset,
+                             int nSize )
+{
+    ub8 nAmont  = (ub8) nSize;
+
+    if( CheckError( OCILobWrite2(
+        poConnection->hSvcCtx,
+        hError,
+        phLocator,
+        (ub8*) &nAmont,
+        (ub8*) NULL,
+        (ub8) nOffset,
+        (dvoid*) pBuffer,
+        (ub8) nSize,
+        (ub1) OCI_ONE_PIECE,
+        (dvoid *) 0,
+        (OCICallbackLobWrite2) 0,
+        (ub2) 0,
+        (ub1) SQLCS_IMPLICIT ), hError ) )
+    {
+        return 0;
+    }
+
+    return nAmont;
+}
 char* OWStatement::ReadCLob( OCILobLocator* phLocator )
 {
     ub4 nSize  = 0;
@@ -1712,7 +1926,9 @@ bool CheckError( sword nStatus, OCIError* hError )
     case OCI_CONTINUE:
         CPLError( CE_Failure, CPLE_AppDefined, "OCI_CONTINUE\n" );
         break;
-    case OCI_ERROR: case OCI_SUCCESS_WITH_INFO:
+    case OCI_ERROR: 
+
+    case OCI_SUCCESS_WITH_INFO:
 
         if( hError == NULL)
         {
@@ -1729,8 +1945,8 @@ bool CheckError( sword nStatus, OCIError* hError )
             return false;
         }
 
-        CPLError( CE_Failure, CPLE_AppDefined, "%.*s",
-            static_cast<int>(sizeof(szMsg)), szMsg );
+        CPLError( CE_Failure, CPLE_AppDefined, "%s", szMsg );
+
         break;
 
     default:
@@ -1745,8 +1961,8 @@ bool CheckError( sword nStatus, OCIError* hError )
                 (text *) NULL, &nCode, szMsg,
                 (ub4) sizeof(szMsg), OCI_HTYPE_ERROR);
 
-            CPLError( CE_Failure, CPLE_AppDefined, "%.*s",
-                static_cast<int>(sizeof(szMsg)), szMsg );
+            CPLError( CE_Failure, CPLE_AppDefined, "%s", szMsg );
+
             break;
     }
 
diff --git a/frmts/georaster/oci_wrapper.h b/frmts/georaster/oci_wrapper.h
index c62002b..562027d 100644
--- a/frmts/georaster/oci_wrapper.h
+++ b/frmts/georaster/oci_wrapper.h
@@ -1,5 +1,4 @@
 /******************************************************************************
- * $Id: oci_wrapper.h 35929 2016-10-25 16:09:00Z goatbar $
  *
  * Name:     oci_wrapper.h
  * Project:  Oracle Spatial GeoRaster Driver
@@ -267,6 +266,8 @@ public:
                             const char* pszUserIn,
                             const char* pszPasswordIn,
                             const char* pszServerIn );
+    explicit            OWConnection(
+                            OCIExtProcContext* poWithContext );
     virtual            ~OWConnection();
 
 private:
@@ -283,10 +284,15 @@ private:
 
     bool                bSuceeeded;
 
+    bool                bExtProc;
+
     char*               pszUser;
     char*               pszPassword;
     char*               pszServer;
 
+    char*               pszExtProcUser;
+    char*               pszExtProcSchema;
+
     OCIType*            hNumArrayTDO;
     OCIType*            hGeometryTDO;
     OCIType*            hGeoRasterTDO;
@@ -294,6 +300,8 @@ private:
     OCIType*            hElemArrayTDO;
     OCIType*            hOrdnArrayTDO;
 
+    void                QueryVersion();
+
 public:
 
     OWStatement*        CreateStatement( const char* pszStatement );
@@ -311,6 +319,8 @@ public:
     void                DestroyType( sdo_geometry** pphData );
     void                CreateType( OCIArray** phData , OCIType* type);
     void                DestroyType( OCIArray** phData );
+    void                DestroyType( OCIType* phType );
+
     OCIType*            DescribeType( const char *pszTypeName );
 
     bool                Succeeded() { return bSuceeeded; };
@@ -329,6 +339,10 @@ public:
     bool                Commit(); // OCITransCommit()
     bool                StartTransaction(); //  //OCITransStart()
     bool                EndTransaction() {return Commit(); }
+
+    bool                IsExtProc() { return bExtProc; }
+    char*               GetExtProcUser() { return pszExtProcUser; };
+    char*               GetExtProcSchema() { return pszExtProcSchema; };
 };
 
 /***************************************************************************/
@@ -394,10 +408,14 @@ public:
                             int nCount );
     unsigned long       ReadBlob( OCILobLocator* phLocator,
                             void* pBuffer, int nSize );
+    unsigned long       ReadBlob( OCILobLocator* phLocator,
+                            void* pBuffer, int nOffset, int nSize );
     char*               ReadCLob( OCILobLocator* phLocator );
     void                WriteCLob( OCILobLocator** pphLocator, char* pszData );
     bool                WriteBlob( OCILobLocator* phLocator,
                             void* pBuffer, int nSize );
+    int                 WriteBlob( OCILobLocator* phLocator,
+                            void* pBuffer, int nOffset, int nSize );
     int                 GetElement( OCIArray** ppoData,
                             int nIndex, int* pnResult );
     double              GetElement( OCIArray** ppoData,
@@ -406,6 +424,7 @@ public:
                             int nValue );
     void                AddElement( OCIArray* ppoData,
                             double dfValue );
+    unsigned long       GetBlobLength( OCILobLocator* phLocator );
 };
 
 #endif /* ifndef _ORCL_WRAP_H_INCLUDED */
diff --git a/frmts/grib/gribdataset.cpp b/frmts/grib/gribdataset.cpp
index afb276c..cef1a99 100644
--- a/frmts/grib/gribdataset.cpp
+++ b/frmts/grib/gribdataset.cpp
@@ -64,7 +64,7 @@
 #include "gdal_priv.h"
 #include "ogr_spatialref.h"
 
-CPL_CVSID("$Id: gribdataset.cpp 37827 2017-03-23 06:07:27Z goatbar $");
+CPL_CVSID("$Id: gribdataset.cpp 38010 2017-04-14 15:07:56Z rouault $");
 
 static CPLMutex *hGRIBMutex = NULL;
 
@@ -614,6 +614,7 @@ GDALDataset *GRIBDataset::Open( GDALOpenInfo *poOpenInfo )
     // Create band objects.
     for (uInt4 i = 0; i < oInventories.length(); ++i)
     {
+        inventoryType *psInv = oInventories.get(i);
         GRIBRasterBand *gribBand = NULL;
         uInt4 bandNr = i + 1;
         if (bandNr == 1)
@@ -623,7 +624,7 @@ GDALDataset *GRIBDataset::Open( GDALOpenInfo *poOpenInfo )
             double *data = NULL;
             grib_MetaData *metaData = NULL;
             GRIBRasterBand::ReadGribData(grib_fp, 0,
-                                         oInventories.get(i)->subgNum,
+                                         psInv->subgNum,
                                          &data, &metaData);
             if( data == NULL || metaData == NULL || metaData->gds.Nx < 1 ||
                 metaData->gds.Ny < 1 )
@@ -651,9 +652,9 @@ GDALDataset *GRIBDataset::Open( GDALOpenInfo *poOpenInfo )
             // Set the DataSet's x,y size, georeference and projection from
             // the first GRIB band.
             poDS->SetGribMetaData(metaData);
-            gribBand = new GRIBRasterBand(poDS, bandNr, oInventories.get(i));
+            gribBand = new GRIBRasterBand(poDS, bandNr, psInv);
 
-            if( oInventories.get(i)->GribVersion == 2 )
+            if( psInv->GribVersion == 2 )
                 gribBand->FindPDSTemplate();
 
             gribBand->m_Grib_Data = data;
@@ -661,10 +662,10 @@ GDALDataset *GRIBDataset::Open( GDALOpenInfo *poOpenInfo )
         }
         else
         {
-            gribBand = new GRIBRasterBand(poDS, bandNr, oInventories.get(i));
+            gribBand = new GRIBRasterBand(poDS, bandNr, psInv);
             if( CPLTestBool(CPLGetConfigOption("GRIB_PDS_ALL_BANDS", "ON")) )
             {
-                if( oInventories.get(i)->GribVersion == 2 )
+                if( psInv->GribVersion == 2 )
                     gribBand->FindPDSTemplate();
             }
         }
diff --git a/frmts/gtiff/gt_wkt_srs.cpp b/frmts/gtiff/gt_wkt_srs.cpp
index fe7dfe7..dfbd4f4 100644
--- a/frmts/gtiff/gt_wkt_srs.cpp
+++ b/frmts/gtiff/gt_wkt_srs.cpp
@@ -66,7 +66,7 @@
 #include "tifvsi.h"
 #include "xtiffio.h"
 
-CPL_CVSID("$Id: gt_wkt_srs.cpp 36582 2016-11-30 17:06:18Z goatbar $")
+CPL_CVSID("$Id: gt_wkt_srs.cpp 38045 2017-04-17 17:48:25Z rouault $")
 
 static const geokey_t ProjLinearUnitsInterpCorrectGeoKey =
     static_cast<geokey_t>(3059);
@@ -91,17 +91,13 @@ CPL_C_END
 
 static const char * const papszDatumEquiv[] =
 {
-    "Militar_Geographische_Institut",
-    "Militar_Geographische_Institute",
-    "World_Geodetic_System_1984",
-    "WGS_1984",
-    "WGS_72_Transit_Broadcast_Ephemeris",
-    "WGS_1972_Transit_Broadcast_Ephemeris",
-    "World_Geodetic_System_1972",
-    "WGS_1972",
-    "European_Terrestrial_Reference_System_89",
-    "European_Reference_System_1989",
-    NULL
+  "Militar_Geographische_Institut", "Militar_Geographische_Institute",
+  "World_Geodetic_System_1984", "WGS_1984",
+  "WGS_72_Transit_Broadcast_Ephemeris", "WGS_1972_Transit_Broadcast_Ephemeris",
+  "World_Geodetic_System_1972", "WGS_1972",
+  "European_Terrestrial_Reference_System_89", "European_Reference_System_1989",
+  "D_North_American_1927", "North_American_Datum_1927", // #6863
+  NULL
 };
 
 // Older libgeotiff's won't list this.
diff --git a/frmts/gtiff/libgeotiff/geo_config.h b/frmts/gtiff/libgeotiff/geo_config.h
index 394b348..8350d6f 100644
--- a/frmts/gtiff/libgeotiff/geo_config.h
+++ b/frmts/gtiff/libgeotiff/geo_config.h
@@ -12,6 +12,13 @@
 #define sprintf CPLsprintf
 #endif
 
+/* Hide symbols in GDAL builds --with-hide-internal-symbols */
+#if defined(USE_GCC_VISIBILITY_FLAG)
+#define GTIF_DLL
+#else
+#define GTIF_DLL CPL_DLL
+#endif
+
 #ifdef RENAME_INTERNAL_LIBTIFF_SYMBOLS
 #include "gdal_libtiff_symbol_rename.h"
 #endif
diff --git a/frmts/gtiff/libgeotiff/geo_normalize.h b/frmts/gtiff/libgeotiff/geo_normalize.h
index d466831..887c037 100644
--- a/frmts/gtiff/libgeotiff/geo_normalize.h
+++ b/frmts/gtiff/libgeotiff/geo_normalize.h
@@ -143,45 +143,45 @@ typedef struct {
 
 } GTIFDefn;
 
-int CPL_DLL GTIFGetPCSInfo( int nPCSCode, char **ppszEPSGName,
+int GTIF_DLL GTIFGetPCSInfo( int nPCSCode, char **ppszEPSGName,
                             short *pnProjOp,
                             short *pnUOMLengthCode, short *pnGeogCS );
-int CPL_DLL GTIFGetProjTRFInfo( int nProjTRFCode,
+int GTIF_DLL GTIFGetProjTRFInfo( int nProjTRFCode,
                                 char ** ppszProjTRFName,
                                 short * pnProjMethod,
                                 double * padfProjParms );
-int CPL_DLL GTIFGetGCSInfo( int nGCSCode, char **ppszName,
+int GTIF_DLL GTIFGetGCSInfo( int nGCSCode, char **ppszName,
                             short *pnDatum, short *pnPM, short *pnUOMAngle );
-int CPL_DLL GTIFGetDatumInfo( int nDatumCode, char **ppszName,
+int GTIF_DLL GTIFGetDatumInfo( int nDatumCode, char **ppszName,
                               short * pnEllipsoid );
-int CPL_DLL GTIFGetEllipsoidInfo( int nEllipsoid, char ** ppszName,
+int GTIF_DLL GTIFGetEllipsoidInfo( int nEllipsoid, char ** ppszName,
                                   double * pdfSemiMajor,
                                   double * pdfSemiMinor );
-int CPL_DLL GTIFGetPMInfo( int nPM, char **ppszName,
+int GTIF_DLL GTIFGetPMInfo( int nPM, char **ppszName,
                            double * pdfLongToGreenwich );
 
-double CPL_DLL GTIFAngleStringToDD( const char *pszAngle, int nUOMAngle );
-int CPL_DLL GTIFGetUOMLengthInfo( int nUOMLengthCode,
+double GTIF_DLL GTIFAngleStringToDD( const char *pszAngle, int nUOMAngle );
+int GTIF_DLL GTIFGetUOMLengthInfo( int nUOMLengthCode,
                                   char **ppszUOMName,
                                   double * pdfInMeters );
-int CPL_DLL GTIFGetUOMAngleInfo( int nUOMAngleCode,
+int GTIF_DLL GTIFGetUOMAngleInfo( int nUOMAngleCode,
                                  char **ppszUOMName,
                                  double * pdfInDegrees );
-double CPL_DLL GTIFAngleToDD( double dfAngle, int nUOMAngle );
+double GTIF_DLL GTIFAngleToDD( double dfAngle, int nUOMAngle );
 
 
 /* this should be used to free strings returned by GTIFGet... funcs */
-void CPL_DLL GTIFFreeMemory( char * );
-void CPL_DLL GTIFDeaccessCSV( void );
+void GTIF_DLL GTIFFreeMemory( char * );
+void GTIF_DLL GTIFDeaccessCSV( void );
 
-int CPL_DLL GTIFGetDefn( GTIF *psGTIF, GTIFDefn * psDefn );
-void CPL_DLL GTIFPrintDefn( GTIFDefn *, FILE * );
-GTIFDefn CPL_DLL *GTIFAllocDefn( void );
-void CPL_DLL GTIFFreeDefn( GTIFDefn * );
+int GTIF_DLL GTIFGetDefn( GTIF *psGTIF, GTIFDefn * psDefn );
+void GTIF_DLL GTIFPrintDefn( GTIFDefn *, FILE * );
+GTIFDefn GTIF_DLL *GTIFAllocDefn( void );
+void GTIF_DLL GTIFFreeDefn( GTIFDefn * );
 
-void CPL_DLL SetCSVFilenameHook( const char *(*CSVFileOverride)(const char *) );
+void GTIF_DLL SetCSVFilenameHook( const char *(*CSVFileOverride)(const char *) );
 
-const char CPL_DLL *GTIFDecToDMS( double, const char *, int );
+const char GTIF_DLL *GTIFDecToDMS( double, const char *, int );
 
 /*
  * These are useful for recognising UTM and State Plane, with or without
@@ -193,20 +193,20 @@ const char CPL_DLL *GTIFDecToDMS( double, const char *, int );
 #define MapSys_State_Plane_27	-9003
 #define MapSys_State_Plane_83	-9004
 
-int CPL_DLL   GTIFMapSysToPCS( int MapSys, int Datum, int nZone );
-int CPL_DLL   GTIFMapSysToProj( int MapSys, int nZone );
-int CPL_DLL   GTIFPCSToMapSys( int PCSCode, int * pDatum, int * pZone );
-int CPL_DLL   GTIFProjToMapSys( int ProjCode, int * pZone );
+int GTIF_DLL   GTIFMapSysToPCS( int MapSys, int Datum, int nZone );
+int GTIF_DLL   GTIFMapSysToProj( int MapSys, int nZone );
+int GTIF_DLL   GTIFPCSToMapSys( int PCSCode, int * pDatum, int * pZone );
+int GTIF_DLL   GTIFProjToMapSys( int ProjCode, int * pZone );
 
 /*
  * These are only useful if using libgeotiff with libproj (PROJ.4+).
  */
-char CPL_DLL *GTIFGetProj4Defn( GTIFDefn * );
+char GTIF_DLL *GTIFGetProj4Defn( GTIFDefn * );
 
-int  CPL_DLL  GTIFProj4ToLatLong( GTIFDefn *, int, double *, double * );
-int  CPL_DLL  GTIFProj4FromLatLong( GTIFDefn *, int, double *, double * );
+int  GTIF_DLL  GTIFProj4ToLatLong( GTIFDefn *, int, double *, double * );
+int  GTIF_DLL  GTIFProj4FromLatLong( GTIFDefn *, int, double *, double * );
 
-int  CPL_DLL  GTIFSetFromProj4( GTIF *gtif, const char *proj4 );
+int  GTIF_DLL  GTIFSetFromProj4( GTIF *gtif, const char *proj4 );
 
 #if defined(HAVE_LIBPROJ) && defined(HAVE_PROJECTS_H)
 #  define HAVE_GTIFPROJ4
diff --git a/frmts/gtiff/libgeotiff/geo_simpletags.h b/frmts/gtiff/libgeotiff/geo_simpletags.h
index 721b4de..21327fc 100644
--- a/frmts/gtiff/libgeotiff/geo_simpletags.h
+++ b/frmts/gtiff/libgeotiff/geo_simpletags.h
@@ -54,17 +54,17 @@ typedef struct {
 
 typedef void *STIFF;
 
-void CPL_DLL GTIFSetSimpleTagsMethods(TIFFMethod *method);
+void GTIF_DLL GTIFSetSimpleTagsMethods(TIFFMethod *method);
 
-int CPL_DLL ST_SetKey( ST_TIFF *, int tag, int count,
+int GTIF_DLL ST_SetKey( ST_TIFF *, int tag, int count,
                        int st_type, void *data );
-int CPL_DLL ST_GetKey( ST_TIFF *, int tag, int *count,
+int GTIF_DLL ST_GetKey( ST_TIFF *, int tag, int *count,
                        int *st_type, void **data_ptr );
 
-ST_TIFF CPL_DLL *ST_Create( void );
-void CPL_DLL ST_Destroy( ST_TIFF * );
+ST_TIFF GTIF_DLL *ST_Create( void );
+void GTIF_DLL ST_Destroy( ST_TIFF * );
 
-int CPL_DLL ST_TagType( int tag );
+int GTIF_DLL ST_TagType( int tag );
 
 #if defined(__cplusplus)
 }
diff --git a/frmts/gtiff/libgeotiff/geo_tiffp.h b/frmts/gtiff/libgeotiff/geo_tiffp.h
index f9186c5..553bf4d 100644
--- a/frmts/gtiff/libgeotiff/geo_tiffp.h
+++ b/frmts/gtiff/libgeotiff/geo_tiffp.h
@@ -99,11 +99,11 @@ typedef struct     _TIFFMethod {
  **********************************************************************/
 
 extern gsize_t _gtiff_size[]; /* TIFF data sizes */
-extern void CPL_DLL _GTIFSetDefaultTIFF(TIFFMethod *method);
-extern gdata_t CPL_DLL _GTIFcalloc(gsize_t);
-extern gdata_t CPL_DLL _GTIFrealloc(gdata_t,gsize_t);
-extern void CPL_DLL _GTIFFree(gdata_t data);
-extern void CPL_DLL _GTIFmemcpy(gdata_t out,gdata_t in,gsize_t size);
+extern void GTIF_DLL _GTIFSetDefaultTIFF(TIFFMethod *method);
+extern gdata_t GTIF_DLL _GTIFcalloc(gsize_t);
+extern gdata_t GTIF_DLL _GTIFrealloc(gdata_t,gsize_t);
+extern void GTIF_DLL _GTIFFree(gdata_t data);
+extern void GTIF_DLL _GTIFmemcpy(gdata_t out,gdata_t in,gsize_t size);
 
 #if defined(__cplusplus)
 }
diff --git a/frmts/gtiff/libgeotiff/geotiff.h b/frmts/gtiff/libgeotiff/geotiff.h
index 7b82446..ea11668 100644
--- a/frmts/gtiff/libgeotiff/geotiff.h
+++ b/frmts/gtiff/libgeotiff/geotiff.h
@@ -38,11 +38,11 @@
 /**********************************************************************
  * Do we want to build as a DLL on windows?
  **********************************************************************/
-#if !defined(CPL_DLL)
+#if !defined(GTIF_DLL)
 #  if defined(_WIN32) && defined(BUILD_AS_DLL)
-#    define CPL_DLL     __declspec(dllexport)
+#    define GTIF_DLL     __declspec(dllexport)
 #  else
-#    define CPL_DLL
+#    define GTIF_DLL
 #  endif
 #endif
 
@@ -85,36 +85,36 @@ typedef enum {
  **********************************************************************/
 
 /* TIFF-level interface */
-GTIF CPL_DLL *GTIFNew(void *tif);
-GTIF CPL_DLL *GTIFNewSimpleTags(void *tif);
-GTIF CPL_DLL *GTIFNewWithMethods(void *tif, TIFFMethod*);
-void CPL_DLL  GTIFFree(GTIF *gtif);
-int  CPL_DLL  GTIFWriteKeys(GTIF *gtif);
-void CPL_DLL  GTIFDirectoryInfo(GTIF *gtif, int *versions, int *keycount);
+GTIF GTIF_DLL *GTIFNew(void *tif);
+GTIF GTIF_DLL *GTIFNewSimpleTags(void *tif);
+GTIF GTIF_DLL *GTIFNewWithMethods(void *tif, TIFFMethod*);
+void GTIF_DLL  GTIFFree(GTIF *gtif);
+int  GTIF_DLL  GTIFWriteKeys(GTIF *gtif);
+void GTIF_DLL  GTIFDirectoryInfo(GTIF *gtif, int *versions, int *keycount);
 
 /* GeoKey Access */
-int  CPL_DLL  GTIFKeyInfo(GTIF *gtif, geokey_t key, int *size, tagtype_t* type);
-int  CPL_DLL  GTIFKeyGet(GTIF *gtif, geokey_t key, void *val, int index,
+int  GTIF_DLL  GTIFKeyInfo(GTIF *gtif, geokey_t key, int *size, tagtype_t* type);
+int  GTIF_DLL  GTIFKeyGet(GTIF *gtif, geokey_t key, void *val, int index,
                          int count);
-int  CPL_DLL  GTIFKeySet(GTIF *gtif, geokey_t keyID, tagtype_t type,
+int  GTIF_DLL  GTIFKeySet(GTIF *gtif, geokey_t keyID, tagtype_t type,
                          int count,...);
 
 /* Metadata Import-Export utilities */
-void  CPL_DLL  GTIFPrint(GTIF *gtif, GTIFPrintMethod print, void *aux);
-int   CPL_DLL  GTIFImport(GTIF *gtif, GTIFReadMethod scan, void *aux);
-char  CPL_DLL *GTIFKeyName(geokey_t key);
-char  CPL_DLL *GTIFValueName(geokey_t key,int value);
-char  CPL_DLL *GTIFTypeName(tagtype_t type);
-char  CPL_DLL *GTIFTagName(int tag);
-int   CPL_DLL  GTIFKeyCode(char * key);
-int   CPL_DLL  GTIFValueCode(geokey_t key,char *value);
-int   CPL_DLL  GTIFTypeCode(char *type);
-int   CPL_DLL  GTIFTagCode(char *tag);
+void  GTIF_DLL  GTIFPrint(GTIF *gtif, GTIFPrintMethod print, void *aux);
+int   GTIF_DLL  GTIFImport(GTIF *gtif, GTIFReadMethod scan, void *aux);
+char  GTIF_DLL *GTIFKeyName(geokey_t key);
+char  GTIF_DLL *GTIFValueName(geokey_t key,int value);
+char  GTIF_DLL *GTIFTypeName(tagtype_t type);
+char  GTIF_DLL *GTIFTagName(int tag);
+int   GTIF_DLL  GTIFKeyCode(char * key);
+int   GTIF_DLL  GTIFValueCode(geokey_t key,char *value);
+int   GTIF_DLL  GTIFTypeCode(char *type);
+int   GTIF_DLL  GTIFTagCode(char *tag);
 
 /* Translation between image/PCS space */
 
-int CPL_DLL    GTIFImageToPCS( GTIF *gtif, double *x, double *y );
-int CPL_DLL    GTIFPCSToImage( GTIF *gtif, double *x, double *y );
+int GTIF_DLL    GTIFImageToPCS( GTIF *gtif, double *x, double *y );
+int GTIF_DLL    GTIFPCSToImage( GTIF *gtif, double *x, double *y );
 
 #if defined(__cplusplus)
 }
diff --git a/frmts/gtiff/libgeotiff/xtiffio.h b/frmts/gtiff/libgeotiff/xtiffio.h
index c551cf9..d5e5c77 100644
--- a/frmts/gtiff/libgeotiff/xtiffio.h
+++ b/frmts/gtiff/libgeotiff/xtiffio.h
@@ -57,20 +57,20 @@ extern "C" {
 /**********************************************************************
  * Do we want to build as a DLL on windows?
  **********************************************************************/
-#if !defined(CPL_DLL)
+#if !defined(GTIF_DLL)
 #  if defined(_WIN32) && defined(BUILD_AS_DLL)
-#    define CPL_DLL     __declspec(dllexport)
+#    define GTIF_DLL     __declspec(dllexport)
 #  else
-#    define CPL_DLL
+#    define GTIF_DLL
 #  endif
 #endif
 
-extern void CPL_DLL XTIFFInitialize(void);
-extern TIFF CPL_DLL * XTIFFOpen(const char* name, const char* mode);
-extern TIFF CPL_DLL * XTIFFFdOpen(int fd, const char* name, const char* mode);
-extern void CPL_DLL XTIFFClose(TIFF *tif);
+extern void GTIF_DLL XTIFFInitialize(void);
+extern TIFF GTIF_DLL * XTIFFOpen(const char* name, const char* mode);
+extern TIFF GTIF_DLL * XTIFFFdOpen(int fd, const char* name, const char* mode);
+extern void GTIF_DLL XTIFFClose(TIFF *tif);
 
-extern TIFF CPL_DLL * XTIFFClientOpen(const char* name, const char* mode,
+extern TIFF GTIF_DLL * XTIFFClientOpen(const char* name, const char* mode,
                                       thandle_t thehandle,
                                       TIFFReadWriteProc, TIFFReadWriteProc,
                                       TIFFSeekProc, TIFFCloseProc,
diff --git a/frmts/hfa/hfadataset.cpp b/frmts/hfa/hfadataset.cpp
index 9cbf24c..fce108c 100644
--- a/frmts/hfa/hfadataset.cpp
+++ b/frmts/hfa/hfadataset.cpp
@@ -62,7 +62,7 @@
 #include "ogr_spatialref.h"
 #include "ogr_srs_api.h"
 
-CPL_CVSID("$Id: hfadataset.cpp 37967 2017-04-12 03:44:05Z goatbar $");
+CPL_CVSID("$Id: hfadataset.cpp 38009 2017-04-14 15:07:49Z rouault $");
 
 static const double R2D = 180.0 / M_PI;
 static const double D2R = M_PI / 180.0;
@@ -2182,8 +2182,10 @@ void HFARasterBand::ReadHistogramMetadata()
         for( int i = 0; i < nNumBins; i++ )
         {
             const double dfNumber = padfWorkBuf[i];
-            if( dfNumber >= std::numeric_limits<GUIntBig>::max() ||
-                dfNumber < std::numeric_limits<GUIntBig>::min() ||
+            if( dfNumber >= static_cast<double>(
+                                std::numeric_limits<GUIntBig>::max()) ||
+                dfNumber < static_cast<double>(
+                                std::numeric_limits<GUIntBig>::min()) ||
                 CPLIsNan(dfNumber) )
             {
                 CPLError(CE_Failure, CPLE_FileIO, "Out of range hist vals.");
diff --git a/frmts/hfa/hfafield.cpp b/frmts/hfa/hfafield.cpp
index 34bc168..7300a30 100644
--- a/frmts/hfa/hfafield.cpp
+++ b/frmts/hfa/hfafield.cpp
@@ -48,7 +48,7 @@
 #include "cpl_string.h"
 #include "cpl_vsi.h"
 
-CPL_CVSID("$Id: hfafield.cpp 37947 2017-04-10 19:20:23Z goatbar $");
+CPL_CVSID("$Id: hfafield.cpp 38009 2017-04-14 15:07:49Z rouault $");
 
 static const int MAX_ENTRY_REPORT = 16;
 
@@ -993,8 +993,10 @@ HFAField::ExtractInstValue( const char *pszField, int nIndexValue,
           memcpy(&fNumber, pabyData + nIndexValue * 4, 4);
           HFAStandard(4, &fNumber);
           dfDoubleRet = fNumber;
-          if( fNumber > std::numeric_limits<int>::max() ||
-              fNumber < std::numeric_limits<int>::min() ||
+          if( dfDoubleRet > static_cast<double>(
+                                            std::numeric_limits<int>::max()) ||
+              dfDoubleRet < static_cast<double>(
+                                            std::numeric_limits<int>::min()) ||
               CPLIsNan(fNumber) )
           {
               CPLError(CE_Failure, CPLE_AppDefined,
diff --git a/frmts/jp2kak/jp2kakdataset.cpp b/frmts/jp2kak/jp2kakdataset.cpp
index 5daf0c8..6d0a7ad 100644
--- a/frmts/jp2kak/jp2kakdataset.cpp
+++ b/frmts/jp2kak/jp2kakdataset.cpp
@@ -53,7 +53,7 @@
 #include <cmath>
 #include <vector>
 
-CPL_CVSID("$Id: jp2kakdataset.cpp 37710 2017-03-14 19:12:48Z goatbar $");
+CPL_CVSID("$Id: jp2kakdataset.cpp 38086 2017-04-21 14:34:14Z rouault $");
 
 // Before v7.5 Kakadu does not advertise its version well
 // After v7.5 Kakadu has KDU_{MAJOR,MINOR,PATCH}_VERSION defines so it's easier
@@ -2205,7 +2205,8 @@ JP2KAKCreateCopy( const char * pszFilename, GDALDataset *poSrcDS,
 
     kdu_compressed_target *poOutputFile = NULL;
     jp2_target jp2_out;
-    const bool bIsJP2 = !EQUAL(CPLGetExtension(pszFilename), "jpc") && !bIsJPX;
+    const bool bIsJP2 = !EQUAL(CPLGetExtension(pszFilename), "jpc") && !bIsJPX &&
+        EQUAL(CSLFetchNameValueDef(papszOptions, "CODEC", "JP2"), "JP2");
     kdu_codestream oCodeStream;
 
     vsil_target oVSILTarget;
@@ -2670,6 +2671,11 @@ void GDALRegister_JP2KAK()
 
     poDriver->SetMetadataItem(GDAL_DMD_CREATIONOPTIONLIST,
 "<CreationOptionList>"
+"   <Option name='CODEC' type='string-select' "
+    "default='according to file extension. If unknown, default to JP2'>"
+"       <Value>JP2</Value>"
+"       <Value>J2K</Value>"
+"   </Option>"
 "   <Option name='QUALITY' type='integer' description="
 "'0.01-100, 100 is lossless'/>"
 "   <Option name='BLOCKXSIZE' type='int' description='Tile Width'/>"
diff --git a/frmts/mbtiles/mbtilesdataset.cpp b/frmts/mbtiles/mbtilesdataset.cpp
index a1a3909..85fc836 100644
--- a/frmts/mbtiles/mbtilesdataset.cpp
+++ b/frmts/mbtiles/mbtilesdataset.cpp
@@ -39,7 +39,7 @@
 #include <math.h>
 #include <algorithm>
 
-CPL_CVSID("$Id: mbtilesdataset.cpp 37720 2017-03-16 16:34:39Z rouault $");
+CPL_CVSID("$Id: mbtilesdataset.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 static const char * const apszAllowedDrivers[] = {"JPEG", "PNG", NULL};
 
@@ -421,7 +421,6 @@ char* MBTilesDataset::FindKey(int iPixel, int iLine)
         //CPLDebug("MBTILES", "Grid value = %s", (const char*)pabyUncompressed);
     }
 
-    struct json_tokener *jstok = NULL;
     json_object* jsobj = NULL;
 
     if (nUncompressedSize == 0)
@@ -429,21 +428,11 @@ char* MBTilesDataset::FindKey(int iPixel, int iLine)
         goto end;
     }
 
-    jstok = json_tokener_new();
-    jsobj = json_tokener_parse_ex(jstok, (const char*)pabyUncompressed, -1);
-    if( jstok->err != json_tokener_success)
+    if( !OGRJSonParse((const char*)pabyUncompressed, &jsobj, true) )
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
-                    "JSON parsing error: %s (at offset %d)",
-                    json_tokener_error_desc(jstok->err),
-                    jstok->char_offset);
-        json_tokener_free(jstok);
-
         goto end;
     }
 
-    json_tokener_free(jstok);
-
     if (json_object_is_type(jsobj, json_type_object))
     {
         poGrid = CPL_json_object_object_get(jsobj, "grid");
@@ -1971,12 +1960,21 @@ GDALDataset* MBTilesDataset::Open(GDALOpenInfo* poOpenInfo)
         poDS->InitRaster ( NULL, nMaxLevel, nBands,
                            dfMinX, dfMinY, dfMaxX, dfMaxY );
 
+        const char* pszFormat = poDS->GetMetadataItem("format");
+        if( pszFormat != NULL && EQUAL(pszFormat, "pbf") )
+        {
+            CPLDebug("MBTiles",
+                     "This files contain vector tiles, "
+                     "not supported by this driver");
+            delete poDS;
+            return NULL;
+        }
+
         if( poDS->eAccess == GA_Update )
         {
             // So that we can edit all potential overviews
             nMinLevel = 0;
 
-            const char* pszFormat = poDS->GetMetadataItem("format");
             if( pszFormat != NULL && (EQUAL(pszFormat, "jpg") || EQUAL(pszFormat, "jpeg")) )
             {
                 poDS->m_eTF = GPKG_TF_JPEG;
@@ -2613,6 +2611,12 @@ CPLErr MBTilesDataset::IBuildOverviews(
     GDALRasterBand*** papapoOverviewBands = (GDALRasterBand ***) CPLCalloc(sizeof(void*),nBands);
     int iCurOverview = 0;
     int nMinZoom = m_nZoomLevel;
+    for( int i = 0; i < m_nOverviewCount; i++ )
+    {
+        MBTilesDataset* poODS = m_papoOverviewDS[i];
+        if( poODS->m_nZoomLevel < nMinZoom )
+            nMinZoom = poODS->m_nZoomLevel;
+    }
     for( int iBand = 0; iBand < nBands; iBand++ )
     {
         papapoOverviewBands[iBand] = (GDALRasterBand **) CPLCalloc(sizeof(void*),nOverviews);
@@ -2631,8 +2635,6 @@ CPLErr MBTilesDataset::IBuildOverviews(
                 continue;
             }
             MBTilesDataset* poODS = m_papoOverviewDS[iOvr];
-            if( poODS->m_nZoomLevel < nMinZoom )
-                nMinZoom = poODS->m_nZoomLevel;
             papapoOverviewBands[iBand][iCurOverview] = poODS->GetRasterBand(iBand+1);
             iCurOverview++ ;
         }
diff --git a/frmts/netcdf/frmt_netcdf.html b/frmts/netcdf/frmt_netcdf.html
index 838e20e..f7c9805 100644
--- a/frmts/netcdf/frmt_netcdf.html
+++ b/frmts/netcdf/frmt_netcdf.html
@@ -214,6 +214,15 @@ or,
     <li>Westernmost_Easting
 </ul>
 
+<h2>Open options</h2>
+
+The followin open options are available:
+<ul>
+<li> <b>HONOUR_VALID_RANGE</b>=YES/NO: (GDAL > 2.2) Whether to set to nodata pixel values
+outside of the validity range indicated by valid_min, valid_max or valid_range
+attributes. Default is YES.
+</ul>
+
 <h2>Creation Issues</h2>
 
 This driver supports creation of NetCDF file following the CF-1 convention.
diff --git a/frmts/netcdf/netcdfdataset.cpp b/frmts/netcdf/netcdfdataset.cpp
index 8977fd3..07cc4bc 100644
--- a/frmts/netcdf/netcdfdataset.cpp
+++ b/frmts/netcdf/netcdfdataset.cpp
@@ -30,7 +30,6 @@
  ****************************************************************************/
 
 #include "cpl_port.h"
-#include "netcdfdataset.h"
 
 #include <cctype>
 #include <cerrno>
@@ -47,6 +46,10 @@
 #include <utility>
 #include <vector>
 
+// Must be included after standard includes, otherwise VS2015 fails when
+// including <ctime>
+#include "netcdfdataset.h"
+
 #include "cpl_conv.h"
 #include "cpl_error.h"
 #include "cpl_minixml.h"
@@ -59,7 +62,7 @@
 #include "ogr_core.h"
 #include "ogr_srs_api.h"
 
-CPL_CVSID("$Id: netcdfdataset.cpp 37984 2017-04-13 19:03:32Z goatbar $");
+CPL_CVSID("$Id: netcdfdataset.cpp 38053 2017-04-18 15:22:27Z rouault $");
 
 // Internal function declarations.
 
@@ -333,7 +336,8 @@ netCDFRasterBand::netCDFRasterBand( netCDFDataset *poNCDFDS,
     // First look for valid_range.
     bool bGotValidRange = false;
     status = nc_inq_att(cdfid, nZId, "valid_range", &atttype, &attlen);
-    if( (status == NC_NOERR) && (attlen == 2))
+    if( (status == NC_NOERR) && (attlen == 2) &&
+        CPLFetchBool(poNCDFDS->GetOpenOptions(), "HONOUR_VALID_RANGE", true) )
     {
         int vrange[2] = { 0, 0 };
         status = nc_get_att_int(cdfid, nZId, "valid_range", vrange);
@@ -5514,6 +5518,7 @@ GDALDataset *netCDFDataset::Open( GDALOpenInfo *poOpenInfo )
     CPLReleaseMutex(hNCMutex);  // Release mutex otherwise we'll deadlock with
                                 // GDALDataset own mutex.
     netCDFDataset *poDS = new netCDFDataset();
+    poDS->papszOpenOptions = CSLDuplicate(poOpenInfo->papszOpenOptions);
     CPLAcquireMutex(hNCMutex, 1000.0);
 
     poDS->SetDescription(poOpenInfo->pszFilename);
@@ -7656,6 +7661,14 @@ void GDALRegister_netCDF()
 "   <Option name='PROFILE_VARIABLES' type='string' description='Comma separated list of field names that must be indexed by the profile dimension'/>"
 "</LayerCreationOptionList>");
 
+    poDriver->SetMetadataItem( GDAL_DMD_OPENOPTIONLIST,
+"<OpenOptionList>"
+"   <Option name='HONOUR_VALID_RANGE' type='boolean' "
+    "description='Whether to set to nodata pixel values outside of the "
+    "validity range' default='YES'/>"
+"</OpenOptionList>" );
+
+
     // Make driver config and capabilities available.
     poDriver->SetMetadataItem("NETCDF_VERSION", nc_inq_libvers());
     poDriver->SetMetadataItem("NETCDF_CONVENTIONS", NCDF_CONVENTIONS_CF_V1_5);
diff --git a/frmts/nitf/frmt_nitf.html b/frmts/nitf/frmt_nitf.html
index bfdf0e9..9093108 100644
--- a/frmts/nitf/frmt_nitf.html
+++ b/frmts/nitf/frmt_nitf.html
@@ -75,15 +75,22 @@ documentation</a>. Starting with GDAL 1.7.0, multi-block images can be written.
 which allow for fast seeking to any block. (Starting with GDAL 1.7.0.)
 <li>C8 means JPEG2000 compression (one block) and is available for
 CreateCopy() and/or Create() methods. JPEG2000 compression is only available
-if the JP2ECW, JP2KAK or Jasper driver is available :
+if the JP2ECW, JP2KAK, JP2OpenJPEG or Jasper driver are available (tried in
+that order when several ones are available)
 <ul>
-<li> JP2ECW : The TARGET and PROFILE JP2ECW-specific creation options can be used.
-Both CreateCopy() and/or Create() methods are available.
-See the <a href="frmt_jp2ecw.html">JP2ECW driver documentation</a>.
-<li> JP2KAK : The general JP2KAK-specific creation options can be used (QUALITY, BLOCKXSIZE, BLOCKYSIZE, GMLPJ2, GeoJP2, LAYERS, ROI).
+<li>  <a href="frmt_jp2ecw.html">JP2ECW</a>:
+The TARGET and PROFILE JP2ECW-specific creation options can be used.
+Both CreateCopy() and/or Create() methods are available. By default the NPJE
+PROFILE will be used (thus implying BLOCKXSIZE=BLOCKYSIZE=1024).
+<li>  <a href="frmt_jp2kak.html">JP2KAK</a> :
+The QUALITY, BLOCKXSIZE, BLOCKYSIZE, LAYERS, ROI JP2KAK-specific creation
+options can be used.
 Only CreateCopy() method is available.
-See the <a href="frmt_jp2kak.html">JP2KAK driver documentation</a>.
-<li>Starting with GDAL 1.7.0, if JP2ECW and JP2KAK drivers are not available, Jasper JPEG2000 driver can be used in the CreateCopy() case.
+<li> <a href="frmt_jp2openjpeg.html">JP2OpenJPEG</a> driver:
+starting with GDAL 2.2.0, in the CreateCopy() case.
+The QUALITY, BLOCKXSIZE and BLOCKYSIZE JP2OpenJPEG-specific creation options
+can be used. By default BLOCKXSIZE=BLOCKYSIZE=1024 will be used.
+<li> Jasper JPEG2000 driver: starting with GDAL 1.7.0, in the CreateCopy() case.
 </ul>
 </ul>
 </li>
diff --git a/frmts/nitf/nitfdataset.cpp b/frmts/nitf/nitfdataset.cpp
index 427ef1c..3ab66f8 100644
--- a/frmts/nitf/nitfdataset.cpp
+++ b/frmts/nitf/nitfdataset.cpp
@@ -61,7 +61,7 @@
 #include "ogr_core.h"
 #include "ogr_srs_api.h"
 
-CPL_CVSID("$Id: nitfdataset.cpp 37346 2017-02-11 23:03:44Z goatbar $");
+CPL_CVSID("$Id: nitfdataset.cpp 38088 2017-04-21 15:05:04Z rouault $");
 
 static bool NITFPatchImageLength( const char *pszFilename,
                                   GUIntBig nImageOffset,
@@ -3821,6 +3821,7 @@ static char **NITFJP2ECWOptions( char **papszOptions )
 
     return papszJP2Options;
 }
+
 /************************************************************************/
 /*                           NITFJP2KAKOptions()                        */
 /*                                                                      */
@@ -3831,27 +3832,46 @@ static char **NITFJP2ECWOptions( char **papszOptions )
 static char **NITFJP2KAKOptions( char **papszOptions )
 
 {
-    char** papszKAKOptions = NULL;
+    char** papszJP2Options = CSLAddString(NULL, "CODEC=J2K");
 
     for( int i = 0; papszOptions != NULL && papszOptions[i] != NULL; i++ )
     {
-       if(      STARTS_WITH_CI(papszOptions[i], "QUALITY=") )
-          papszKAKOptions = CSLAddString(papszKAKOptions, papszOptions[i]);
-       else if (STARTS_WITH_CI(papszOptions[i], "BLOCKXSIZE=") )
-          papszKAKOptions = CSLAddString(papszKAKOptions, papszOptions[i]);
-       else if (STARTS_WITH_CI(papszOptions[i], "BLOCKYSIZE=") )
-          papszKAKOptions = CSLAddString(papszKAKOptions, papszOptions[i]);
-       else if (STARTS_WITH_CI(papszOptions[i], "GMLPJ2=") )
-          papszKAKOptions = CSLAddString(papszKAKOptions, papszOptions[i]);
-       else if (STARTS_WITH_CI(papszOptions[i], "GeoJP2=") )
-          papszKAKOptions = CSLAddString(papszKAKOptions, papszOptions[i]);
-       else if (STARTS_WITH_CI(papszOptions[i], "LAYERS=") )
-          papszKAKOptions = CSLAddString(papszKAKOptions, papszOptions[i]);
-       else if (STARTS_WITH_CI(papszOptions[i], "ROI=") )
-          papszKAKOptions = CSLAddString(papszKAKOptions, papszOptions[i]);
-    }
-
-    return papszKAKOptions;
+        if( STARTS_WITH_CI(papszOptions[i], "QUALITY=") ||
+            STARTS_WITH_CI(papszOptions[i], "BLOCKXSIZE=") ||
+            STARTS_WITH_CI(papszOptions[i], "BLOCKYSIZE=") ||
+            STARTS_WITH_CI(papszOptions[i], "LAYERS=") ||
+            STARTS_WITH_CI(papszOptions[i], "ROI=") )
+        {
+            papszJP2Options = CSLAddString(papszJP2Options, papszOptions[i]);
+        }
+    }
+
+    return papszJP2Options;
+}
+
+/************************************************************************/
+/*                      NITFJP2OPENJPEGOptions()                        */
+/*                                                                      */
+/*      Prepare JP2-in-NITF creation options based in part of the       */
+/*      NITF creation options.                                          */
+/************************************************************************/
+
+static char **NITFJP2OPENJPEGOptions( char **papszOptions )
+
+{
+    char** papszJP2Options = CSLAddString(NULL, "CODEC=J2K");
+
+    for( int i = 0; papszOptions != NULL && papszOptions[i] != NULL; i++ )
+    {
+        if( STARTS_WITH_CI(papszOptions[i], "QUALITY=") ||
+            STARTS_WITH_CI(papszOptions[i], "BLOCKXSIZE=") ||
+            STARTS_WITH_CI(papszOptions[i], "BLOCKYSIZE=") )
+        {
+            papszJP2Options = CSLAddString(papszJP2Options, papszOptions[i]);
+        }
+    }
+
+    return papszJP2Options;
 }
 
 /************************************************************************/
@@ -4002,6 +4022,20 @@ NITFDataset::NITFDatasetCreate( const char *pszFilename, int nXSize, int nYSize,
                                                           &papszTextMD,
                                                           &papszCgmMD );
 
+    const char* pszBlockSize = CSLFetchNameValue(papszFullOptions, "BLOCKSIZE");
+    if(  pszBlockSize!= NULL &&
+        CSLFetchNameValue(papszFullOptions, "BLOCKXSIZE") == NULL )
+    {
+        papszFullOptions = CSLSetNameValue(papszFullOptions,
+                                           "BLOCKXSIZE", pszBlockSize);
+    }
+    if(  pszBlockSize!= NULL &&
+        CSLFetchNameValue(papszFullOptions, "BLOCKYSIZE") == NULL )
+    {
+        papszFullOptions = CSLSetNameValue(papszFullOptions,
+                                           "BLOCKYSIZE", pszBlockSize);
+    }
+
 /* -------------------------------------------------------------------- */
 /*      Create the file.                                                */
 /* -------------------------------------------------------------------- */
@@ -4016,9 +4050,6 @@ NITFDataset::NITFDatasetCreate( const char *pszFilename, int nXSize, int nYSize,
         return NULL;
     }
 
-    CSLDestroy(papszFullOptions);
-    papszFullOptions = NULL;
-
 /* -------------------------------------------------------------------- */
 /*      Various special hacks related to JPEG2000 encoded files.        */
 /* -------------------------------------------------------------------- */
@@ -4040,7 +4071,7 @@ NITFDataset::NITFDatasetCreate( const char *pszFilename, int nXSize, int nYSize,
 
         NITFClose( psFile );
 
-        char** papszJP2Options = NITFJP2ECWOptions(papszOptions);
+        char** papszJP2Options = NITFJP2ECWOptions(papszFullOptions);
         poWritableJ2KDataset =
             poJ2KDriver->Create( osDSName, nXSize, nYSize, nBands, eType,
                                  papszJP2Options );
@@ -4053,6 +4084,7 @@ NITFDataset::NITFDatasetCreate( const char *pszFilename, int nXSize, int nYSize,
             return NULL;
         }
     }
+    CSLDestroy(papszFullOptions);
 
 /* -------------------------------------------------------------------- */
 /*      Open the dataset in update mode.                                */
@@ -4124,6 +4156,12 @@ NITFDataset::NITFCreateCopy(
             }
             if( poJ2KDriver == NULL )
             {
+                /* Try with JP2OPENJPEG as an alternate driver */
+                poJ2KDriver =
+                    GetGDALDriverManager()->GetDriverByName( "JP2OPENJPEG" );
+            }
+            if( poJ2KDriver == NULL )
+            {
                 /* Try with Jasper as an alternate driver */
                 poJ2KDriver =
                     GetGDALDriverManager()->GetDriverByName( "JPEG2000" );
@@ -4178,6 +4216,20 @@ NITFDataset::NITFCreateCopy(
                                                          &papszTextMD,
                                                          &papszCgmMD );
 
+    const char* pszBlockSize = CSLFetchNameValue(papszFullOptions, "BLOCKSIZE");
+    if(  pszBlockSize!= NULL &&
+        CSLFetchNameValue(papszFullOptions, "BLOCKXSIZE") == NULL )
+    {
+        papszFullOptions = CSLSetNameValue(papszFullOptions,
+                                           "BLOCKXSIZE", pszBlockSize);
+    }
+    if(  pszBlockSize!= NULL &&
+        CSLFetchNameValue(papszFullOptions, "BLOCKYSIZE") == NULL )
+    {
+        papszFullOptions = CSLSetNameValue(papszFullOptions,
+                                           "BLOCKYSIZE", pszBlockSize);
+    }
+
 /* -------------------------------------------------------------------- */
 /*      Copy over other source metadata items as creation options       */
 /*      that seem useful.                                               */
@@ -4531,6 +4583,59 @@ NITFDataset::NITFCreateCopy(
         return NULL;
     }
 
+    if ( poJ2KDriver != NULL && EQUAL(poJ2KDriver->GetDescription(), "JP2ECW"))
+    {
+        if( EQUAL(CSLFetchNameValueDef(papszFullOptions, "PROFILE", "NPJE"),
+                  "NPJE") && (nXSize >= 1024 || nYSize >= 1024) )
+        {
+            int nBlockXSize = atoi(
+                CSLFetchNameValueDef(papszFullOptions, "BLOCKXSIZE", "0"));
+            int nBlockYSize = atoi(
+                CSLFetchNameValueDef(papszFullOptions, "BLOCKYSIZE", "0"));
+            if( nBlockXSize > 0 && nBlockXSize != 1024 )
+            {
+                CPLError(CE_Warning, CPLE_AppDefined,
+                    "BLOCKXSIZE != 1024 inconsistent with PROFILE=NPJE");
+            }
+            if( nBlockYSize > 0 && nBlockYSize != 1024 )
+            {
+                CPLError(CE_Warning, CPLE_AppDefined,
+                    "BLOCKYSIZE != 1024 inconsistent with PROFILE=NPJE");
+            }
+            if( nBlockXSize == 0 )
+            {
+                papszFullOptions = CSLSetNameValue(papszFullOptions,
+                                                   "BLOCKXSIZE", "1024");
+            }
+            if( nBlockYSize == 0 )
+            {
+                papszFullOptions = CSLSetNameValue(papszFullOptions,
+                                                   "BLOCKYSIZE", "1024");
+            }
+        }
+    }
+    else if( poJ2KDriver != NULL &&
+             EQUAL(poJ2KDriver->GetDescription(), "JP2OPENJPEG") &&
+             (nXSize >= 1024 || nYSize >= 1024) )
+    {
+        // The JP2OPENJPEG driver uses 1024 block size by default. Set it
+        // explicitly for NITFCreate() purposes.
+        int nBlockXSize = atoi(
+            CSLFetchNameValueDef(papszFullOptions, "BLOCKXSIZE", "0"));
+        int nBlockYSize = atoi(
+            CSLFetchNameValueDef(papszFullOptions, "BLOCKYSIZE", "0"));
+        if( nBlockXSize == 0 )
+        {
+            papszFullOptions = CSLSetNameValue(papszFullOptions,
+                                                "BLOCKXSIZE", "1024");
+        }
+        if( nBlockYSize == 0 )
+        {
+            papszFullOptions = CSLSetNameValue(papszFullOptions,
+                                                "BLOCKYSIZE", "1024");
+        }
+    }
+
     if (!NITFCreate( pszFilename, nXSize, nYSize, poSrcDS->GetRasterCount(),
                 GDALGetDataTypeSize( eType ), pszPVType,
                 papszFullOptions ))
@@ -4541,9 +4646,6 @@ NITFDataset::NITFCreateCopy(
         return NULL;
     }
 
-    CSLDestroy( papszFullOptions );
-    papszFullOptions = NULL;
-
 /* ==================================================================== */
 /*      JPEG2000 case.  We need to write the data through a J2K         */
 /*      driver in pixel interleaved form.                               */
@@ -4557,6 +4659,7 @@ NITFDataset::NITFCreateCopy(
         {
             CSLDestroy(papszCgmMD);
             CSLDestroy(papszTextMD);
+            CSLDestroy( papszFullOptions );
             return NULL;
         }
 
@@ -4572,7 +4675,7 @@ NITFDataset::NITFCreateCopy(
         GDALDataset *poJ2KDataset = NULL;
         if (EQUAL(poJ2KDriver->GetDescription(), "JP2ECW"))
         {
-            char** papszJP2Options = NITFJP2ECWOptions(papszOptions);
+            char** papszJP2Options = NITFJP2ECWOptions(papszFullOptions);
             poJ2KDataset =
                 poJ2KDriver->CreateCopy( osDSName, poSrcDS, FALSE,
                                          papszJP2Options,
@@ -4581,12 +4684,21 @@ NITFDataset::NITFCreateCopy(
         }
         else if (EQUAL(poJ2KDriver->GetDescription(), "JP2KAK"))
         {
-           char** papszKAKOptions = NITFJP2KAKOptions(papszOptions);
+           char** papszJP2Options = NITFJP2KAKOptions(papszFullOptions);
+            poJ2KDataset =
+                poJ2KDriver->CreateCopy( osDSName, poSrcDS, FALSE,
+                                         papszJP2Options,
+                                         pfnProgress, pProgressData );
+            CSLDestroy(papszJP2Options);
+        }
+        else if (EQUAL(poJ2KDriver->GetDescription(), "JP2OPENJPEG"))
+        {
+           char** papszJP2Options = NITFJP2OPENJPEGOptions(papszFullOptions);
             poJ2KDataset =
                 poJ2KDriver->CreateCopy( osDSName, poSrcDS, FALSE,
-                                         papszKAKOptions,
+                                         papszJP2Options,
                                          pfnProgress, pProgressData );
-            CSLDestroy(papszKAKOptions);
+            CSLDestroy(papszJP2Options);
         }
         else
         {
@@ -4601,6 +4713,7 @@ NITFDataset::NITFCreateCopy(
         {
             CSLDestroy(papszCgmMD);
             CSLDestroy(papszTextMD);
+            CSLDestroy( papszFullOptions );
             return NULL;
         }
 
@@ -4618,6 +4731,7 @@ NITFDataset::NITFCreateCopy(
         {
             CSLDestroy(papszCgmMD);
             CSLDestroy(papszTextMD);
+            CSLDestroy( papszFullOptions );
             return NULL;
         }
 
@@ -4628,6 +4742,7 @@ NITFDataset::NITFCreateCopy(
         {
             CSLDestroy(papszCgmMD);
             CSLDestroy(papszTextMD);
+            CSLDestroy( papszFullOptions );
             return NULL;
         }
     }
@@ -4643,13 +4758,14 @@ NITFDataset::NITFCreateCopy(
         {
             CSLDestroy(papszCgmMD);
             CSLDestroy(papszTextMD);
+            CSLDestroy( papszFullOptions );
             return NULL;
         }
         GUIntBig nImageOffset = psFile->pasSegmentInfo[0].nSegmentStart;
 
         const bool bSuccess =
             NITFWriteJPEGImage( poSrcDS, psFile->fp, nImageOffset,
-                                papszOptions,
+                                papszFullOptions,
                                 pfnProgress, pProgressData );
 
         if( !bSuccess )
@@ -4657,6 +4773,7 @@ NITFDataset::NITFCreateCopy(
             NITFClose( psFile );
             CSLDestroy(papszCgmMD);
             CSLDestroy(papszTextMD);
+            CSLDestroy( papszFullOptions );
             return NULL;
         }
 
@@ -4676,6 +4793,7 @@ NITFDataset::NITFCreateCopy(
         {
             CSLDestroy(papszCgmMD);
             CSLDestroy(papszTextMD);
+            CSLDestroy( papszFullOptions );
             return NULL;
         }
 
@@ -4686,6 +4804,7 @@ NITFDataset::NITFCreateCopy(
         {
             CSLDestroy(papszCgmMD);
             CSLDestroy(papszTextMD);
+            CSLDestroy( papszFullOptions );
             return NULL;
         }
 #endif /* def JPEG_SUPPORTED */
@@ -4702,6 +4821,7 @@ NITFDataset::NITFCreateCopy(
         {
             CSLDestroy(papszCgmMD);
             CSLDestroy(papszTextMD);
+            CSLDestroy( papszFullOptions );
             return NULL;
         }
 
@@ -4721,6 +4841,7 @@ NITFDataset::NITFCreateCopy(
         {
             CSLDestroy(papszCgmMD);
             CSLDestroy(papszTextMD);
+            CSLDestroy( papszFullOptions );
             return NULL;
         }
 
@@ -4730,6 +4851,7 @@ NITFDataset::NITFCreateCopy(
             delete poDstDS;
             CSLDestroy(papszCgmMD);
             CSLDestroy(papszTextMD);
+            CSLDestroy( papszFullOptions );
             return NULL;
         }
 
@@ -4782,6 +4904,7 @@ NITFDataset::NITFCreateCopy(
             delete poDstDS;
             CSLDestroy(papszCgmMD);
             CSLDestroy(papszTextMD);
+            CSLDestroy( papszFullOptions );
             return NULL;
         }
     }
@@ -4819,6 +4942,7 @@ NITFDataset::NITFCreateCopy(
 
     CSLDestroy(papszCgmMD);
     CSLDestroy(papszTextMD);
+    CSLDestroy( papszFullOptions );
 
     return poDstDS;
 }
@@ -5577,9 +5701,6 @@ NITFWriteJPEGImage( GDALDataset *poSrcDS, VSILFILE *fp, vsi_l_offset nStartOffse
     int nNPPBH = nXSize;
     int nNPPBV = nYSize;
 
-    if( CSLFetchNameValue( papszOptions, "BLOCKSIZE" ) != NULL )
-        nNPPBH = nNPPBV = atoi(CSLFetchNameValue( papszOptions, "BLOCKSIZE" ));
-
     if( CSLFetchNameValue( papszOptions, "BLOCKXSIZE" ) != NULL )
         nNPPBH = atoi(CSLFetchNameValue( papszOptions, "BLOCKXSIZE" ));
 
@@ -5872,7 +5993,7 @@ void GDALRegister_NITF()
 #ifdef JPEG_SUPPORTED
                 "C3/M3=JPEG compression. "
 #endif
-                "C8=JP2 compression through the JP2ECW driver"
+                "C8=JP2 compression through the JP2ECW/JP2KAK/JP2OPENJPEG/JPEG2000 driver"
                 "'>"
 "       <Value>NC</Value>"
 #ifdef JPEG_SUPPORTED
diff --git a/frmts/nitf/nitffile.c b/frmts/nitf/nitffile.c
index ba4ebec..654dacc 100644
--- a/frmts/nitf/nitffile.c
+++ b/frmts/nitf/nitffile.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: nitffile.c 36457 2016-11-23 00:18:37Z rouault $
+ * $Id: nitffile.c 38086 2017-04-21 14:34:14Z rouault $
  *
  * Project:  NITF Read/Write Library
  * Purpose:  Module responsible for opening NITF file, populating NITFFile
@@ -34,7 +34,7 @@
 #include "cpl_conv.h"
 #include "cpl_string.h"
 
-CPL_CVSID("$Id: nitffile.c 36457 2016-11-23 00:18:37Z rouault $");
+CPL_CVSID("$Id: nitffile.c 38086 2017-04-21 14:34:14Z rouault $");
 
 CPL_INLINE static void CPL_IGNORE_RET_VAL_INT(CPL_UNUSED int unused) {}
 
@@ -619,9 +619,6 @@ int NITFCreate( const char *pszFilename,
     nNPPBH = nPixels;
     nNPPBV = nLines;
 
-    if( CSLFetchNameValue( papszOptions, "BLOCKSIZE" ) != NULL )
-        nNPPBH = nNPPBV = atoi(CSLFetchNameValue( papszOptions, "BLOCKSIZE" ));
-
     if( CSLFetchNameValue( papszOptions, "BLOCKXSIZE" ) != NULL )
         nNPPBH = atoi(CSLFetchNameValue( papszOptions, "BLOCKXSIZE" ));
 
@@ -634,7 +631,7 @@ int NITFCreate( const char *pszFilename,
     if( CSLFetchNameValue( papszOptions, "NPPBV" ) != NULL )
         nNPPBV = atoi(CSLFetchNameValue( papszOptions, "NPPBV" ));
 
-    if (EQUAL(pszIC, "NC") &&
+    if ( (EQUAL(pszIC, "NC") || EQUAL(pszIC, "C8")) &&
         (nPixels > 8192 || nLines > 8192) &&
         nNPPBH == nPixels && nNPPBV == nLines)
     {
@@ -649,7 +646,7 @@ int NITFCreate( const char *pszFilename,
             * ((GIntBig) nPixels *nLines)
             * nBands;
     }
-    else if (EQUAL(pszIC, "NC") &&
+    else if ( (EQUAL(pszIC, "NC") || EQUAL(pszIC, "C8")) &&
              nPixels > 8192 && nNPPBH == nPixels)
     {
         /* See MIL-STD-2500-C, paragraph 5.4.2.2-d */
@@ -671,7 +668,7 @@ int NITFCreate( const char *pszFilename,
             * ((GIntBig) nPixels * (nNBPC * nNPPBV))
             * nBands;
     }
-    else if (EQUAL(pszIC, "NC") &&
+    else if ( (EQUAL(pszIC, "NC") || EQUAL(pszIC, "C8")) &&
              nLines > 8192 && nNPPBV == nLines)
     {
         /* See MIL-STD-2500-C, paragraph 5.4.2.2-d */
diff --git a/frmts/openjpeg/GNUmakefile b/frmts/openjpeg/GNUmakefile
index 76f7e26..28a2780 100644
--- a/frmts/openjpeg/GNUmakefile
+++ b/frmts/openjpeg/GNUmakefile
@@ -3,18 +3,23 @@ include ../../GDALmake.opt
 
 OBJ	=	openjpegdataset.o
 
-
-
 ifneq ($(OPENJPEG_VERSION),)
 CPPFLAGS 	:=	$(CPPFLAGS) -DOPENJPEG_VERSION=$(OPENJPEG_VERSION)
 endif
 
 CPPFLAGS        :=       -I.. $(CPPFLAGS)
 
-
 default:	$(OBJ:.o=.$(OBJ_EXT))
 
 clean:
-	rm -f $(OBJ) $(O_OBJ)
+	rm -f $(OBJ) $(O_OBJ) *.so *.lo
 
 install-obj:	$(O_OBJ:.o=.$(OBJ_EXT))
+
+PLUGIN_SO = gdal_JP2OpenJPEG.so
+
+plugin: $(PLUGIN_SO)
+
+$(PLUGIN_SO): $(OBJ)
+	$(LD_SHARED) $(LNK_FLAGS) $(OBJ) $(CONFIG_LIBS_INS) $(LIBS) \
+	-o $(PLUGIN_SO)
diff --git a/frmts/openjpeg/makefile.vc b/frmts/openjpeg/makefile.vc
index e591b25..59c9fbd 100644
--- a/frmts/openjpeg/makefile.vc
+++ b/frmts/openjpeg/makefile.vc
@@ -3,6 +3,8 @@ OBJ	=	openjpegdataset.obj
 
 GDAL_ROOT	=	..\..
 
+PLUGIN_DLL = gdal_JP2OpenJPEG.dll
+
 !INCLUDE $(GDAL_ROOT)\nmake.opt
 
 EXTRAFLAGS = -I.. $(OPENJPEG_CFLAGS) $(OPENJPEG_VERSION_CFLAGS)
@@ -16,4 +18,17 @@ default:	$(OBJ)
 
 clean:
 	-del *.obj
-
+	-del *.dll
+	-del *.exp
+	-del *.lib
+	-del *.manifest
+	
+plugin:	$(PLUGIN_DLL)
+
+$(PLUGIN_DLL): $(OBJ)
+	link /dll $(LDEBUG) /out:$(PLUGIN_DLL) $(OBJ) $(OPENJPEG_LIB) $(GDALLIB)
+	if exist $(PLUGIN_DLL).manifest mt -manifest $(PLUGIN_DLL).manifest -outputresource:$(PLUGIN_DLL);2
+
+plugin-install:
+	-mkdir $(PLUGINDIR)
+	$(INSTALL) $(PLUGIN_DLL) $(PLUGINDIR)
\ No newline at end of file
diff --git a/frmts/openjpeg/openjpegdataset.cpp b/frmts/openjpeg/openjpegdataset.cpp
index 69bed33..47d309e 100644
--- a/frmts/openjpeg/openjpegdataset.cpp
+++ b/frmts/openjpeg/openjpegdataset.cpp
@@ -57,7 +57,7 @@
 
 #include <algorithm>
 
-CPL_CVSID("$Id: openjpegdataset.cpp 37373 2017-02-13 11:49:40Z rouault $");
+CPL_CVSID("$Id: openjpegdataset.cpp 38088 2017-04-21 15:05:04Z rouault $");
 
 /************************************************************************/
 /*                  JP2OpenJPEGDataset_ErrorCallback()                  */
@@ -1703,26 +1703,26 @@ GDALDataset *JP2OpenJPEGDataset::Open( GDALOpenInfo * poOpenInfo )
     }
     else
     {
-        poDS->bUseSetDecodeArea =
-            (poDS->nRasterXSize == (int)nTileW &&
-            poDS->nRasterYSize == (int)nTileH &&
-            (poDS->nRasterXSize > 1024 ||
-            poDS->nRasterYSize > 1024));
+    poDS->bUseSetDecodeArea =
+        (poDS->nRasterXSize == (int)nTileW &&
+         poDS->nRasterYSize == (int)nTileH &&
+         (poDS->nRasterXSize > 1024 ||
+          poDS->nRasterYSize > 1024));
 
-        /* Sentinel2 preview datasets are 343x343 and 60m are 1830x1830, but they */
-        /* are tiled with tile dimensions 2048x2048. It would be a waste of */
-        /* memory to allocate such big blocks */
-        if( poDS->nRasterXSize < (int)nTileW &&
-            poDS->nRasterYSize < (int)nTileH )
-        {
-            poDS->bUseSetDecodeArea = TRUE;
-            nTileW = poDS->nRasterXSize;
-            nTileH = poDS->nRasterYSize;
-            if (nTileW > 2048) nTileW = 2048;
-            if (nTileH > 2048) nTileH = 2048;
-        }
-        else if (poDS->bUseSetDecodeArea)
-        {
+    /* Sentinel2 preview datasets are 343x343 and 60m are 1830x1830, but they */
+    /* are tiled with tile dimensions 2048x2048. It would be a waste of */
+    /* memory to allocate such big blocks */
+    if( poDS->nRasterXSize < (int)nTileW &&
+        poDS->nRasterYSize < (int)nTileH )
+    {
+        poDS->bUseSetDecodeArea = TRUE;
+        nTileW = poDS->nRasterXSize;
+        nTileH = poDS->nRasterYSize;
+        if (nTileW > 2048) nTileW = 2048;
+        if (nTileH > 2048) nTileH = 2048;
+    }
+    else if (poDS->bUseSetDecodeArea)
+    {
             // Arbitrary threshold... ~4 million at least needed for the GRIB2
             // images mentioned below.
             if( nTileH == 1 && nTileW < 20 * 1024 * 1024 )
@@ -1732,9 +1732,9 @@ GDALDataset *JP2OpenJPEGDataset::Open( GDALOpenInfo * poOpenInfo )
             }
             else
             {
-                if (nTileW > 1024) nTileW = 1024;
-                if (nTileH > 1024) nTileH = 1024;
-            }
+        if (nTileW > 1024) nTileW = 1024;
+        if (nTileH > 1024) nTileH = 1024;
+    }
         }
     }
 
@@ -2242,6 +2242,8 @@ GDALDataset * JP2OpenJPEGDataset::CreateCopy( const char * pszFilename,
         return NULL;
     }
 
+    // NOTE: if changing the default block size, the logic in nitfdataset.cpp
+    // CreateCopy() will have to be changed as well.
     int nBlockXSize =
         atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "1024"));
     int nBlockYSize =
@@ -2678,6 +2680,128 @@ GDALDataset * JP2OpenJPEGDataset::CreateCopy( const char * pszFilename,
             return NULL;
     }
 
+    /* ---------------------------------------------------------------- */
+    /* If the input driver is identifed as "GEORASTER" the following    */
+    /* section will try to dump a ORACLE GeoRaster JP2 BLOB into a file */
+    /* ---------------------------------------------------------------- */
+
+    if ( EQUAL( poSrcDS->GetDriverName(), "GEORASTER" ) )
+    {
+        const char* pszGEOR_compress = poSrcDS->GetMetadataItem("COMPRESSION", 
+                                                "IMAGE_STRUCTURE");
+
+        if( pszGEOR_compress == NULL )
+        {
+            pszGEOR_compress = "NONE";
+        }
+
+        /* Check if the JP2 BLOB needs re-shaping */
+
+        bool bGEOR_reshape = false;
+
+        const char* apszIgnoredOptions[] = {
+            "BLOCKXSIZE", "BLOCKYSIZE", "QUALITY", "REVERSIBLE",
+            "RESOLUTIONS", "PROGRESSION", "SOP", "EPH",
+            "YCBCR420", "YCC", "NBITS", "1BIT_ALPHA", "PRECINCTS",
+            "TILEPARTS", "CODEBLOCK_WIDTH", "CODEBLOCK_HEIGHT", NULL };
+
+        for( int i = 0; apszIgnoredOptions[i]; i ++)
+        {
+            if( CSLFetchNameValue(papszOptions, apszIgnoredOptions[i]) )
+            {
+                bGEOR_reshape = true;
+            }
+        }
+
+        if( CSLFetchNameValue( papszOptions, "USE_SRC_CODESTREAM" ) )
+        {
+            bGEOR_reshape = false;
+        }
+
+        char** papszGEOR_files = poSrcDS->GetFileList();
+
+        if( EQUAL( pszGEOR_compress, "JP2-F" ) &&
+            CSLCount( papszGEOR_files ) > 0 &&
+            bGEOR_reshape == false )
+        {
+
+            const char* pszVsiOciLob = papszGEOR_files[0];
+
+            VSILFILE *fpBlob = VSIFOpenL( pszVsiOciLob, "r" );
+            if( fpBlob == NULL )
+            {
+                CPLError(CE_Failure, CPLE_AppDefined, "Cannot open %s",
+                         pszVsiOciLob);
+                delete poGMLJP2Box;
+                return NULL;
+            }
+            VSILFILE* fp = VSIFOpenL( pszFilename, "w+b" );
+            if( fp == NULL )
+            {
+                CPLError(CE_Failure, CPLE_AppDefined, "Cannot create %s",
+                         pszFilename);
+                delete poGMLJP2Box;
+                VSIFCloseL(fpBlob);
+                return NULL;
+            }
+
+            VSIFSeekL( fpBlob, 0, SEEK_END );
+
+            size_t nBlobSize = static_cast<size_t>(VSIFTellL( fpBlob));
+            size_t nChunk = (size_t) ( GDALGetCacheMax() * 0.25 );
+            size_t nSize = 0;
+            size_t nCount = 0;
+
+            void *pBuffer = (GByte*) VSI_MALLOC_VERBOSE( nChunk );
+            if( pBuffer == NULL )
+            {
+                delete poGMLJP2Box;
+                VSIFCloseL(fpBlob);
+                VSIFCloseL( fp );
+                return NULL;
+            }
+
+            VSIFSeekL( fpBlob, 0, SEEK_SET );
+
+            while( ( nSize = VSIFReadL( pBuffer, 1, nChunk, fpBlob ) ) > 0 )
+            {
+                VSIFWriteL( pBuffer, 1, nSize, fp );
+                nCount += nSize;
+                pfnProgress( (float) nCount / (float) nBlobSize, 
+                                 NULL, pProgressData );
+            }
+
+            CPLFree( pBuffer );
+            VSIFCloseL( fpBlob );
+
+            VSIFCloseL( fp );
+
+            /* Return the GDALDaset object */
+
+            GDALOpenInfo oOpenInfo(pszFilename, GA_Update);
+            GDALDataset *poDS = JP2OpenJPEGDataset::Open(&oOpenInfo);
+
+            /* Copy essential metadata */
+
+            double adfGeoTransform[6];
+
+            if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None )
+            {
+                poDS->SetGeoTransform( adfGeoTransform );
+            }
+
+            const char* pszWKT = poSrcDS->GetProjectionRef();
+
+            if( pszWKT != NULL && pszWKT[0] != '\0' )
+            {
+                poDS->SetProjection( pszWKT );
+            }
+
+            delete poGMLJP2Box;
+            return poDS;
+        }
+    }
+
 /* -------------------------------------------------------------------- */
 /*      Setup encoder                                                  */
 /* -------------------------------------------------------------------- */
@@ -2920,7 +3044,7 @@ GDALDataset * JP2OpenJPEGDataset::CreateCopy( const char * pszFilename,
         if( nGMLJP2Version == 2 && bJPXOption )
             ftypBox.AppendWritableData(4, "jpx "); /* Branding */
         else
-            ftypBox.AppendWritableData(4, "jp2 "); /* Branding */
+        ftypBox.AppendWritableData(4, "jp2 "); /* Branding */
         ftypBox.AppendUInt32(0); /* minimum version */
         ftypBox.AppendWritableData(4, "jp2 "); /* Compatibility list: first value */
 
diff --git a/frmts/pdf/pdfio.h b/frmts/pdf/pdfio.h
index 20dbfb3..e96f317 100644
--- a/frmts/pdf/pdfio.h
+++ b/frmts/pdf/pdfio.h
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: pdfio.h 36501 2016-11-25 14:09:24Z rouault $
+ * $Id: pdfio.h 38070 2017-04-20 12:02:25Z rouault $
  *
  * Project:  PDF driver
  * Purpose:  GDALDataset driver for PDF dataset.
@@ -85,9 +85,18 @@ class VSIPDFFileStream: public BaseStream
         virtual void       close() override;
 
     private:
-        /* Added in poppler 0.15.0 */
+#ifdef POPPLER_BASE_STREAM_HAS_TWO_ARGS
+        /* getChars/hasGetChars added in poppler 0.15.0
+         * POPPLER_BASE_STREAM_HAS_TWO_ARGS true from poppler 0.16,
+         * This test will be wrong for poppler 0.15 or 0.16,
+         * but will still compile correctly.
+         */
         virtual GBool hasGetChars() override;
         virtual int getChars(int nChars, Guchar *buffer) override;
+#else
+        virtual GBool hasGetChars() ;
+        virtual int getChars(int nChars, Guchar *buffer) ;
+#endif
 
         VSIPDFFileStream  *poParent;
         GooString         *poFilename;
diff --git a/frmts/plmosaic/plmosaicdataset.cpp b/frmts/plmosaic/plmosaicdataset.cpp
index 511a97c..c1367ca 100644
--- a/frmts/plmosaic/plmosaicdataset.cpp
+++ b/frmts/plmosaic/plmosaicdataset.cpp
@@ -36,7 +36,7 @@
 
 #include "ogrgeojsonreader.h"
 
-CPL_CVSID("$Id: plmosaicdataset.cpp 37371 2017-02-13 11:41:59Z rouault $");
+CPL_CVSID("$Id: plmosaicdataset.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 // g++ -fPIC -g -Wall frmts/plmosaic/*.cpp -shared -o gdal_PLMOSAIC.so -Iport -Igcore -Iogr -Iogr/ogrsf_frmts -Iogr/ogrsf_frmts/geojson/libjson -L. -lgdal
 
@@ -524,19 +524,13 @@ json_object* PLMosaicDataset::RunRequest(const char* pszURL,
         return NULL;
     }
 
-    json_tokener* jstok = json_tokener_new();
-    json_object* poObj
-        = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1);
-    if( jstok->err != json_tokener_success)
+    json_object* poObj = NULL;
+    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
+    if( !OGRJSonParse(pszText, &poObj, true) )
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
-                    "JSON parsing error: %s (at offset %d)",
-                    json_tokener_error_desc(jstok->err), jstok->char_offset);
-        json_tokener_free(jstok);
         CPLHTTPDestroyResult(psResult);
         return NULL;
     }
-    json_tokener_free(jstok);
 
     CPLHTTPDestroyResult(psResult);
 
diff --git a/frmts/raw/gtxdataset.cpp b/frmts/raw/gtxdataset.cpp
index 2c14fe1..f95522a 100644
--- a/frmts/raw/gtxdataset.cpp
+++ b/frmts/raw/gtxdataset.cpp
@@ -32,7 +32,7 @@
 #include "ogr_srs_api.h"
 #include "rawdataset.h"
 
-CPL_CVSID("$Id: gtxdataset.cpp 37977 2017-04-13 15:25:27Z rouault $");
+CPL_CVSID("$Id: gtxdataset.cpp 38048 2017-04-17 19:04:42Z rouault $");
 
 /**
 
@@ -202,7 +202,7 @@ GDALDataset *GTXDataset::Open( GDALOpenInfo * poOpenInfo )
     if( CPLFetchBool(poOpenInfo->papszOpenOptions,
                                 "SHIFT_ORIGIN_IN_MINUS_180_PLUS_180", false) )
     {
-        if( poDS->adfGeoTransform[0] < -180.0 )
+        if( poDS->adfGeoTransform[0] < -180.0 - poDS->adfGeoTransform[1] )
             poDS->adfGeoTransform[0] += 360.0;
         else if( poDS->adfGeoTransform[0] > 180.0 )
             poDS->adfGeoTransform[0] -= 360.0;
diff --git a/frmts/vrt/vrtderivedrasterband.cpp b/frmts/vrt/vrtderivedrasterband.cpp
index 76b9f89..b138e64 100644
--- a/frmts/vrt/vrtderivedrasterband.cpp
+++ b/frmts/vrt/vrtderivedrasterband.cpp
@@ -49,7 +49,7 @@
 
 /*! @cond Doxygen_Suppress */
 
-CPL_CVSID("$Id: vrtderivedrasterband.cpp 36981 2016-12-20 19:46:41Z rouault $");
+CPL_CVSID("$Id: vrtderivedrasterband.cpp 38039 2017-04-16 13:08:39Z rouault $");
 
 // #define GDAL_VRT_DISABLE_PYTHON
 // #define PYTHONSO_DEFAULT "libpython2.7.so"
@@ -1385,7 +1385,7 @@ bool VRTDerivedRasterBand::InitializePython()
     PyObject* poCompiledString = Py_CompileString(
         ("import numpy\n"
         "def GDALCreateNumpyArray(buffer, dtype, height, width):\n"
-        "    return numpy.frombuffer(buffer, dtype.decode('ascii'))."
+        "    return numpy.frombuffer(buffer, str(dtype.decode('ascii')))."
                                                 "reshape([height, width])\n"
         "\n" + m_poPrivate->m_osCode).c_str(),
         osModuleName, Py_file_input);
diff --git a/gcore/gdal_version.h b/gcore/gdal_version.h
index f273397..7ea8324 100644
--- a/gcore/gdal_version.h
+++ b/gcore/gdal_version.h
@@ -1,4 +1,4 @@
-/* $Id: gdal_version.h 37989 2017-04-14 07:47:45Z rouault $ */
+/* $Id: gdal_version.h 38124 2017-04-23 12:46:45Z rouault $ */
 
 /* -------------------------------------------------------------------- */
 /*      GDAL Version Information.                                       */
@@ -23,8 +23,8 @@
 #endif
 
 #ifndef GDAL_RELEASE_DATE
-#  define GDAL_RELEASE_DATE     20170414
+#  define GDAL_RELEASE_DATE     20170423
 #endif
 #ifndef GDAL_RELEASE_NAME
-#  define GDAL_RELEASE_NAME     "2.2.0beta1"
+#  define GDAL_RELEASE_NAME     "2.2.0beta2"
 #endif
diff --git a/gcore/gdaldllmain.cpp b/gcore/gdaldllmain.cpp
index f987d8e..1564ba3 100644
--- a/gcore/gdaldllmain.cpp
+++ b/gcore/gdaldllmain.cpp
@@ -79,10 +79,13 @@ void GDALDestroy(void)
     OGRCleanupAll();
     bInGDALGlobalDestructor = false;
 
-    /* See https://trac.osgeo.org/gdal/ticket/6139 */
+    /* See corresponding bug reports: */
+    /* https://trac.osgeo.org/gdal/ticket/6139 */
+    /* https://trac.osgeo.org/gdal/ticket/6868 */
     /* Needed in case no driver manager has been instantiated. */
     CPLFreeConfig();
     CPLFinalizeTLS();
+    CPLCleanupErrorMutex();
     CPLCleanupMasterMutex();
 }
 
diff --git a/man/man1/gdal-config.1 b/man/man1/gdal-config.1
index 4bd3ece..4ab9453 100644
--- a/man/man1/gdal-config.1
+++ b/man/man1/gdal-config.1
@@ -1,4 +1,4 @@
-.TH "gdal-config" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal-config" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal2tiles.1 b/man/man1/gdal2tiles.1
index cd745cc..60bc433 100644
--- a/man/man1/gdal2tiles.1
+++ b/man/man1/gdal2tiles.1
@@ -1,4 +1,4 @@
-.TH "gdal2tiles" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal2tiles" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_calc.1 b/man/man1/gdal_calc.1
index 14813ce..7416e06 100644
--- a/man/man1/gdal_calc.1
+++ b/man/man1/gdal_calc.1
@@ -1,4 +1,4 @@
-.TH "gdal_calc" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_calc" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_contour.1 b/man/man1/gdal_contour.1
index df968bd..b891543 100644
--- a/man/man1/gdal_contour.1
+++ b/man/man1/gdal_contour.1
@@ -1,4 +1,4 @@
-.TH "gdal_contour" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_contour" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_edit.1 b/man/man1/gdal_edit.1
index 950bf3d..5c7620e 100644
--- a/man/man1/gdal_edit.1
+++ b/man/man1/gdal_edit.1
@@ -1,4 +1,4 @@
-.TH "gdal_edit" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_edit" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_fillnodata.1 b/man/man1/gdal_fillnodata.1
index ae9d423..430d872 100644
--- a/man/man1/gdal_fillnodata.1
+++ b/man/man1/gdal_fillnodata.1
@@ -1,4 +1,4 @@
-.TH "gdal_fillnodata" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_fillnodata" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_grid.1 b/man/man1/gdal_grid.1
index b54d759..60ac800 100644
--- a/man/man1/gdal_grid.1
+++ b/man/man1/gdal_grid.1
@@ -1,4 +1,4 @@
-.TH "gdal_grid" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_grid" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_merge.1 b/man/man1/gdal_merge.1
index c6f150e..be4b80f 100644
--- a/man/man1/gdal_merge.1
+++ b/man/man1/gdal_merge.1
@@ -1,4 +1,4 @@
-.TH "gdal_merge" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_merge" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_pansharpen.1 b/man/man1/gdal_pansharpen.1
index 97ed076..4e08bed 100644
--- a/man/man1/gdal_pansharpen.1
+++ b/man/man1/gdal_pansharpen.1
@@ -1,4 +1,4 @@
-.TH "gdal_pansharpen" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_pansharpen" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_polygonize.1 b/man/man1/gdal_polygonize.1
index e32af86..8523fba 100644
--- a/man/man1/gdal_polygonize.1
+++ b/man/man1/gdal_polygonize.1
@@ -1,4 +1,4 @@
-.TH "gdal_polygonize" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_polygonize" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_proximity.1 b/man/man1/gdal_proximity.1
index 7ce8fe7..f997c2c 100644
--- a/man/man1/gdal_proximity.1
+++ b/man/man1/gdal_proximity.1
@@ -1,4 +1,4 @@
-.TH "gdal_proximity" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_proximity" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_rasterize.1 b/man/man1/gdal_rasterize.1
index 1fdecb3..48844c2 100644
--- a/man/man1/gdal_rasterize.1
+++ b/man/man1/gdal_rasterize.1
@@ -1,4 +1,4 @@
-.TH "gdal_rasterize" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_rasterize" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_retile.1 b/man/man1/gdal_retile.1
index b95c701..c4efa3d 100644
--- a/man/man1/gdal_retile.1
+++ b/man/man1/gdal_retile.1
@@ -1,4 +1,4 @@
-.TH "gdal_retile" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_retile" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_sieve.1 b/man/man1/gdal_sieve.1
index ccaed58..45da4ae 100644
--- a/man/man1/gdal_sieve.1
+++ b/man/man1/gdal_sieve.1
@@ -1,4 +1,4 @@
-.TH "gdal_sieve" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_sieve" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_translate.1 b/man/man1/gdal_translate.1
index ea2e4ac..61b66c0 100644
--- a/man/man1/gdal_translate.1
+++ b/man/man1/gdal_translate.1
@@ -1,4 +1,4 @@
-.TH "gdal_translate" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_translate" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_utilities.1 b/man/man1/gdal_utilities.1
index 9363398..91ff88f 100644
--- a/man/man1/gdal_utilities.1
+++ b/man/man1/gdal_utilities.1
@@ -1,4 +1,4 @@
-.TH "gdal_utilities" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_utilities" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdaladdo.1 b/man/man1/gdaladdo.1
index 607873d..2f9fca0 100644
--- a/man/man1/gdaladdo.1
+++ b/man/man1/gdaladdo.1
@@ -1,4 +1,4 @@
-.TH "gdaladdo" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdaladdo" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalbuildvrt.1 b/man/man1/gdalbuildvrt.1
index 1499a47..2443dfc 100644
--- a/man/man1/gdalbuildvrt.1
+++ b/man/man1/gdalbuildvrt.1
@@ -1,4 +1,4 @@
-.TH "gdalbuildvrt" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalbuildvrt" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalcompare.1 b/man/man1/gdalcompare.1
index 8ddb1a8..d08ffd4 100644
--- a/man/man1/gdalcompare.1
+++ b/man/man1/gdalcompare.1
@@ -1,4 +1,4 @@
-.TH "gdalcompare" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalcompare" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdaldem.1 b/man/man1/gdaldem.1
index b1f8452..fbcbbc4 100644
--- a/man/man1/gdaldem.1
+++ b/man/man1/gdaldem.1
@@ -1,4 +1,4 @@
-.TH "gdaldem" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdaldem" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalinfo.1 b/man/man1/gdalinfo.1
index 5c3ce47..149db02 100644
--- a/man/man1/gdalinfo.1
+++ b/man/man1/gdalinfo.1
@@ -1,4 +1,4 @@
-.TH "gdalinfo" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalinfo" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdallocationinfo.1 b/man/man1/gdallocationinfo.1
index 7b4f74b..77cbacf 100644
--- a/man/man1/gdallocationinfo.1
+++ b/man/man1/gdallocationinfo.1
@@ -1,4 +1,4 @@
-.TH "gdallocationinfo" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdallocationinfo" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalmanage.1 b/man/man1/gdalmanage.1
index 82b3984..ebb376f 100644
--- a/man/man1/gdalmanage.1
+++ b/man/man1/gdalmanage.1
@@ -1,4 +1,4 @@
-.TH "gdalmanage" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalmanage" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalmove.1 b/man/man1/gdalmove.1
index 733ad5d..d5ce4be 100644
--- a/man/man1/gdalmove.1
+++ b/man/man1/gdalmove.1
@@ -1,4 +1,4 @@
-.TH "gdalmove" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalmove" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalsrsinfo.1 b/man/man1/gdalsrsinfo.1
index ad8eb6d..3bdf31b 100644
--- a/man/man1/gdalsrsinfo.1
+++ b/man/man1/gdalsrsinfo.1
@@ -1,4 +1,4 @@
-.TH "gdalsrsinfo" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalsrsinfo" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdaltindex.1 b/man/man1/gdaltindex.1
index d4323b5..35bf4da 100644
--- a/man/man1/gdaltindex.1
+++ b/man/man1/gdaltindex.1
@@ -1,4 +1,4 @@
-.TH "gdaltindex" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdaltindex" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdaltransform.1 b/man/man1/gdaltransform.1
index d4370cb..88582ac 100644
--- a/man/man1/gdaltransform.1
+++ b/man/man1/gdaltransform.1
@@ -1,4 +1,4 @@
-.TH "gdaltransform" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdaltransform" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalwarp.1 b/man/man1/gdalwarp.1
index 4a0e94d..68595a1 100644
--- a/man/man1/gdalwarp.1
+++ b/man/man1/gdalwarp.1
@@ -1,4 +1,4 @@
-.TH "gdalwarp" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalwarp" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gnm_utilities.1 b/man/man1/gnm_utilities.1
index 60832eb..739e127 100644
--- a/man/man1/gnm_utilities.1
+++ b/man/man1/gnm_utilities.1
@@ -1,4 +1,4 @@
-.TH "gnm_utilities" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gnm_utilities" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gnmanalyse.1 b/man/man1/gnmanalyse.1
index 5f14422..88138b2 100644
--- a/man/man1/gnmanalyse.1
+++ b/man/man1/gnmanalyse.1
@@ -1,4 +1,4 @@
-.TH "gnmanalyse" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gnmanalyse" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gnmmanage.1 b/man/man1/gnmmanage.1
index 6b00bd5..b44e333 100644
--- a/man/man1/gnmmanage.1
+++ b/man/man1/gnmmanage.1
@@ -1,4 +1,4 @@
-.TH "gnmmanage" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "gnmmanage" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/nearblack.1 b/man/man1/nearblack.1
index aaf9fca..751bee9 100644
--- a/man/man1/nearblack.1
+++ b/man/man1/nearblack.1
@@ -1,4 +1,4 @@
-.TH "nearblack" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "nearblack" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogr2ogr.1 b/man/man1/ogr2ogr.1
index 3cb6426..3ada4d8 100644
--- a/man/man1/ogr2ogr.1
+++ b/man/man1/ogr2ogr.1
@@ -1,4 +1,4 @@
-.TH "ogr2ogr" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "ogr2ogr" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogr_utilities.1 b/man/man1/ogr_utilities.1
index 67efea3..b170bf5 100644
--- a/man/man1/ogr_utilities.1
+++ b/man/man1/ogr_utilities.1
@@ -1,4 +1,4 @@
-.TH "ogr_utilities" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "ogr_utilities" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogrinfo.1 b/man/man1/ogrinfo.1
index 5383ae8..f729895 100644
--- a/man/man1/ogrinfo.1
+++ b/man/man1/ogrinfo.1
@@ -1,4 +1,4 @@
-.TH "ogrinfo" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "ogrinfo" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogrlineref.1 b/man/man1/ogrlineref.1
index 4042834..eb05590 100644
--- a/man/man1/ogrlineref.1
+++ b/man/man1/ogrlineref.1
@@ -1,4 +1,4 @@
-.TH "ogrlineref" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "ogrlineref" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogrmerge.1 b/man/man1/ogrmerge.1
index 7c79a9f..4d78957 100644
--- a/man/man1/ogrmerge.1
+++ b/man/man1/ogrmerge.1
@@ -1,4 +1,4 @@
-.TH "ogrmerge" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "ogrmerge" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogrtindex.1 b/man/man1/ogrtindex.1
index d42733a..779bdef 100644
--- a/man/man1/ogrtindex.1
+++ b/man/man1/ogrtindex.1
@@ -1,4 +1,4 @@
-.TH "ogrtindex" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "ogrtindex" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/pct2rgb.1 b/man/man1/pct2rgb.1
index 601a249..ccc4335 100644
--- a/man/man1/pct2rgb.1
+++ b/man/man1/pct2rgb.1
@@ -1,4 +1,4 @@
-.TH "pct2rgb" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "pct2rgb" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/rgb2pct.1 b/man/man1/rgb2pct.1
index 0580413..d4f103f 100644
--- a/man/man1/rgb2pct.1
+++ b/man/man1/rgb2pct.1
@@ -1,4 +1,4 @@
-.TH "rgb2pct" 1 "Fri Apr 14 2017" "GDAL" \" -*- nroff -*-
+.TH "rgb2pct" 1 "Sun Apr 23 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/ogr/ogrgeometryfactory.cpp b/ogr/ogrgeometryfactory.cpp
index 81fbe6b..4e567a2 100644
--- a/ogr/ogrgeometryfactory.cpp
+++ b/ogr/ogrgeometryfactory.cpp
@@ -62,7 +62,7 @@
 #define UNUSED_IF_NO_GEOS
 #endif
 
-CPL_CVSID("$Id: ogrgeometryfactory.cpp 37865 2017-03-30 20:13:32Z rouault $");
+CPL_CVSID("$Id: ogrgeometryfactory.cpp 38117 2017-04-23 07:36:29Z rouault $");
 
 /************************************************************************/
 /*                           createFromWkb()                            */
@@ -1337,7 +1337,8 @@ typedef enum
  * @param papszOptions a list of strings for passing options
  *
  * @return a single resulting geometry (either OGRPolygon, OGRCurvePolygon,
- * OGRMultiPolygon, OGRMultiSurface or OGRGeometryCollection).
+ * OGRMultiPolygon, OGRMultiSurface or OGRGeometryCollection). Returns a
+ * POLYGON EMPTY in the case of nPolygonCount being 0.
  */
 
 OGRGeometry* OGRGeometryFactory::organizePolygons( OGRGeometry **papoPolygons,
@@ -1345,6 +1346,14 @@ OGRGeometry* OGRGeometryFactory::organizePolygons( OGRGeometry **papoPolygons,
                                                    int *pbIsValidGeometry,
                                                    const char** papszOptions )
 {
+    if( nPolygonCount == 0 )
+    {
+        if( pbIsValidGeometry )
+            *pbIsValidGeometry = TRUE;
+
+        return new OGRPolygon();
+    }
+
     OGRGeometry* geom = NULL;
     OrganizePolygonMethod method = METHOD_NORMAL;
     bool bHasCurves = false;
diff --git a/ogr/ogrsf_frmts/amigocloud/ogramigoclouddatasource.cpp b/ogr/ogrsf_frmts/amigocloud/ogramigoclouddatasource.cpp
index cc69eb6..b0b64ea 100644
--- a/ogr/ogrsf_frmts/amigocloud/ogramigoclouddatasource.cpp
+++ b/ogr/ogrsf_frmts/amigocloud/ogramigoclouddatasource.cpp
@@ -31,7 +31,7 @@
 #include "ogrgeojsonreader.h"
 #include <sstream>
 
-CPL_CVSID("$Id: ogramigoclouddatasource.cpp 36979 2016-12-20 18:40:40Z rouault $");
+CPL_CVSID("$Id: ogramigoclouddatasource.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 CPLString OGRAMIGOCLOUDGetOptionValue(const char* pszFilename, const char* pszOptionName);
 
@@ -426,21 +426,13 @@ json_object* OGRAmigoCloudDataSource::RunPOST(const char*pszURL, const char *psz
 
     CPLDebug( "AMIGOCLOUD", "RunPOST Response:%s", psResult->pabyData );
 
-    json_tokener* jstok = NULL;
     json_object* poObj = NULL;
-
-    jstok = json_tokener_new();
-    poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1);
-    if( jstok->err != json_tokener_success)
+    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
+    if( !OGRJSonParse(pszText, &poObj, true) )
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
-                  "JSON parsing error: %s (at offset %d)",
-                  json_tokener_error_desc(jstok->err), jstok->char_offset);
-        json_tokener_free(jstok);
         CPLHTTPDestroyResult(psResult);
         return NULL;
     }
-    json_tokener_free(jstok);
 
     CPLHTTPDestroyResult(psResult);
 
@@ -523,21 +515,13 @@ json_object* OGRAmigoCloudDataSource::RunDELETE(const char*pszURL)
 
     CPLDebug( "AMIGOCLOUD", "RunDELETE Response:%s", psResult->pabyData );
 
-    json_tokener* jstok = NULL;
     json_object* poObj = NULL;
-
-    jstok = json_tokener_new();
-    poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1);
-    if( jstok->err != json_tokener_success)
+    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
+    if( !OGRJSonParse(pszText, &poObj, true) )
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
-                  "JSON parsing error: %s (at offset %d)",
-                  json_tokener_error_desc(jstok->err), jstok->char_offset);
-        json_tokener_free(jstok);
         CPLHTTPDestroyResult(psResult);
         return NULL;
     }
-    json_tokener_free(jstok);
 
     CPLHTTPDestroyResult(psResult);
 
@@ -616,21 +600,13 @@ json_object* OGRAmigoCloudDataSource::RunGET(const char*pszURL)
 
     CPLDebug( "AMIGOCLOUD", "RunGET Response:%s", psResult->pabyData );
 
-    json_tokener* jstok = NULL;
     json_object* poObj = NULL;
-
-    jstok = json_tokener_new();
-    poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1);
-    if( jstok->err != json_tokener_success)
+    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
+    if( !OGRJSonParse(pszText, &poObj, true) )
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
-                  "JSON parsing error: %s (at offset %d)",
-                  json_tokener_error_desc(jstok->err), jstok->char_offset);
-        json_tokener_free(jstok);
         CPLHTTPDestroyResult(psResult);
         return NULL;
     }
-    json_tokener_free(jstok);
 
     CPLHTTPDestroyResult(psResult);
 
@@ -731,21 +707,13 @@ json_object* OGRAmigoCloudDataSource::RunSQL(const char* pszUnescapedSQL)
 
     CPLDebug( "AMIGOCLOUD", "RunSQL Response:%s", psResult->pabyData );
 
-    json_tokener* jstok = NULL;
     json_object* poObj = NULL;
-
-    jstok = json_tokener_new();
-    poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1);
-    if( jstok->err != json_tokener_success)
+    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
+    if( !OGRJSonParse(pszText, &poObj, true) )
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
-                    "JSON parsing error: %s (at offset %d)",
-                    json_tokener_error_desc(jstok->err), jstok->char_offset);
-        json_tokener_free(jstok);
         CPLHTTPDestroyResult(psResult);
         return NULL;
     }
-    json_tokener_free(jstok);
 
     CPLHTTPDestroyResult(psResult);
 
diff --git a/ogr/ogrsf_frmts/carto/ogrcartodatasource.cpp b/ogr/ogrsf_frmts/carto/ogrcartodatasource.cpp
index b5045a9..086cc39 100644
--- a/ogr/ogrsf_frmts/carto/ogrcartodatasource.cpp
+++ b/ogr/ogrsf_frmts/carto/ogrcartodatasource.cpp
@@ -30,7 +30,7 @@
 #include "ogr_pgdump.h"
 #include "ogrgeojsonreader.h"
 
-CPL_CVSID("$Id: ogrcartodatasource.cpp 36979 2016-12-20 18:40:40Z rouault $");
+CPL_CVSID("$Id: ogrcartodatasource.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 /************************************************************************/
 /*                        OGRCARTODataSource()                        */
@@ -608,21 +608,13 @@ json_object* OGRCARTODataSource::RunSQL(const char* pszUnescapedSQL)
     if( strlen((const char*)psResult->pabyData) < 1000 )
         CPLDebug( "CARTO", "RunSQL Response:%s", psResult->pabyData );
 
-    json_tokener* jstok = NULL;
     json_object* poObj = NULL;
-
-    jstok = json_tokener_new();
-    poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1);
-    if( jstok->err != json_tokener_success)
+    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
+    if( !OGRJSonParse(pszText, &poObj, true) )
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
-                    "JSON parsing error: %s (at offset %d)",
-                    json_tokener_error_desc(jstok->err), jstok->char_offset);
-        json_tokener_free(jstok);
         CPLHTTPDestroyResult(psResult);
         return NULL;
     }
-    json_tokener_free(jstok);
 
     CPLHTTPDestroyResult(psResult);
 
diff --git a/ogr/ogrsf_frmts/couchdb/ogrcouchdbdatasource.cpp b/ogr/ogrsf_frmts/couchdb/ogrcouchdbdatasource.cpp
index b05092d..e828400 100644
--- a/ogr/ogrsf_frmts/couchdb/ogrcouchdbdatasource.cpp
+++ b/ogr/ogrsf_frmts/couchdb/ogrcouchdbdatasource.cpp
@@ -30,7 +30,7 @@
 #include "ogrgeojsonreader.h"
 #include "swq.h"
 
-CPL_CVSID("$Id: ogrcouchdbdatasource.cpp 36981 2016-12-20 19:46:41Z rouault $");
+CPL_CVSID("$Id: ogrcouchdbdatasource.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 /************************************************************************/
 /*                        OGRCouchDBDataSource()                        */
@@ -1122,23 +1122,13 @@ json_object* OGRCouchDBDataSource::REQUEST(const char* pszVerb,
         return NULL;
     }
 
-    json_tokener* jstok = NULL;
     json_object* jsobj = NULL;
-
-    jstok = json_tokener_new();
-    jsobj = json_tokener_parse_ex(jstok, (const char*)psResult->pabyData, -1);
-    if( jstok->err != json_tokener_success)
+    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
+    if( !OGRJSonParse(pszText, &jsobj, true) )
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
-                    "JSON parsing error: %s (at offset %d)",
-                    json_tokener_error_desc(jstok->err), jstok->char_offset);
-
-        json_tokener_free(jstok);
-
         CPLHTTPDestroyResult(psResult);
         return NULL;
     }
-    json_tokener_free(jstok);
 
     CPLHTTPDestroyResult(psResult);
     return jsobj;
diff --git a/ogr/ogrsf_frmts/csv/ogrcsvdriver.cpp b/ogr/ogrsf_frmts/csv/ogrcsvdriver.cpp
index da8dfae..7f22922 100644
--- a/ogr/ogrsf_frmts/csv/ogrcsvdriver.cpp
+++ b/ogr/ogrsf_frmts/csv/ogrcsvdriver.cpp
@@ -44,7 +44,7 @@
 #include "gdal.h"
 #include "gdal_priv.h"
 
-CPL_CVSID("$Id: ogrcsvdriver.cpp 37367 2017-02-13 05:32:41Z goatbar $");
+CPL_CVSID("$Id: ogrcsvdriver.cpp 38032 2017-04-16 08:26:01Z rouault $");
 
 static CPLMutex* hMutex = NULL;
 static std::map<CPLString, GDALDataset*> *poMap = NULL;
@@ -83,7 +83,7 @@ static int OGRCSVDriverIdentify( GDALOpenInfo* poOpenInfo )
               STARTS_WITH_CI(osBaseFilename, "AllStatesFedCodes_") ||
               (osBaseFilename.size() > 2
                && STARTS_WITH_CI(osBaseFilename+2, "_Features_")) ||
-              (osBaseFilename.size()
+              (osBaseFilename.size() > 2
                && STARTS_WITH_CI(osBaseFilename+2, "_FedCodes_"))) &&
              (EQUAL(osExt, "txt") || EQUAL(osExt, "zip")) )
         {
diff --git a/ogr/ogrsf_frmts/elastic/ogrelasticdatasource.cpp b/ogr/ogrsf_frmts/elastic/ogrelasticdatasource.cpp
index 1ce1741..3de310d 100644
--- a/ogr/ogrsf_frmts/elastic/ogrelasticdatasource.cpp
+++ b/ogr/ogrsf_frmts/elastic/ogrelasticdatasource.cpp
@@ -35,7 +35,7 @@
 #include "ogrgeojsonreader.h"
 #include "swq.h"
 
-CPL_CVSID("$Id: ogrelasticdatasource.cpp 37072 2017-01-09 12:54:57Z rouault $");
+CPL_CVSID("$Id: ogrelasticdatasource.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 /************************************************************************/
 /*                        OGRElasticDataSource()                        */
@@ -375,21 +375,13 @@ json_object* OGRElasticDataSource::RunRequest(const char* pszURL, const char* ps
         return NULL;
     }
 
-    json_tokener* jstok = NULL;
     json_object* poObj = NULL;
-
-    jstok = json_tokener_new();
-    poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1);
-    if( jstok->err != json_tokener_success)
+    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
+    if( !OGRJSonParse(pszText, &poObj, true) )
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
-                    "JSON parsing error: %s (at offset %d)",
-                    json_tokener_error_desc(jstok->err), jstok->char_offset);
-        json_tokener_free(jstok);
         CPLHTTPDestroyResult(psResult);
         return NULL;
     }
-    json_tokener_free(jstok);
 
     CPLHTTPDestroyResult(psResult);
 
diff --git a/ogr/ogrsf_frmts/geojson/ogresrijsonreader.cpp b/ogr/ogrsf_frmts/geojson/ogresrijsonreader.cpp
index c38b6da..085ba4d 100644
--- a/ogr/ogrsf_frmts/geojson/ogresrijsonreader.cpp
+++ b/ogr/ogrsf_frmts/geojson/ogresrijsonreader.cpp
@@ -50,7 +50,7 @@
 #include "ogrgeojsonutils.h"
 // #include "symbol_renames.h"
 
-CPL_CVSID("$Id: ogresrijsonreader.cpp 37374 2017-02-13 11:59:01Z goatbar $");
+CPL_CVSID("$Id: ogresrijsonreader.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 /************************************************************************/
 /*                          OGRESRIJSONReader()                         */
@@ -82,26 +82,15 @@ OGRESRIJSONReader::~OGRESRIJSONReader()
 
 OGRErr OGRESRIJSONReader::Parse( const char* pszText )
 {
-    if( NULL != pszText )
+    json_object *jsobj = NULL;
+    if( NULL != pszText && !OGRJSonParse(pszText, &jsobj, true) )
     {
-        json_tokener* jstok = json_tokener_new();
-        json_object* jsobj = json_tokener_parse_ex(jstok, pszText, -1);
-        if( jstok->err != json_tokener_success)
-        {
-            CPLError( CE_Failure, CPLE_AppDefined,
-                      "ESRIJSON parsing error: %s (at offset %d)",
-                      json_tokener_error_desc(jstok->err), jstok->char_offset);
-
-            json_tokener_free(jstok);
-            return OGRERR_CORRUPT_DATA;
-        }
-        json_tokener_free(jstok);
-
-        // JSON tree is shared for while lifetime of the reader object
-        // and will be released in the destructor.
-        poGJObject_ = jsobj;
+        return OGRERR_CORRUPT_DATA;
     }
 
+    // JSON tree is shared for while lifetime of the reader object
+    // and will be released in the destructor.
+    poGJObject_ = jsobj;
     return OGRERR_NONE;
 }
 
diff --git a/ogr/ogrsf_frmts/geojson/ogrgeojsondatasource.cpp b/ogr/ogrsf_frmts/geojson/ogrgeojsondatasource.cpp
index 65b2d7a..b393865 100644
--- a/ogr/ogrsf_frmts/geojson/ogrgeojsondatasource.cpp
+++ b/ogr/ogrsf_frmts/geojson/ogrgeojsondatasource.cpp
@@ -57,7 +57,7 @@
 // #include "symbol_renames.h"
 
 
-CPL_CVSID("$Id: ogrgeojsondatasource.cpp 37374 2017-02-13 11:59:01Z goatbar $");
+CPL_CVSID("$Id: ogrgeojsondatasource.cpp 38109 2017-04-22 22:26:06Z rouault $");
 
 /************************************************************************/
 /*                           OGRGeoJSONDataSource()                     */
@@ -247,7 +247,7 @@ OGRLayer* OGRGeoJSONDataSource::ICreateLayer( const char* pszNameIn,
         CSLFetchNameValue(papszOptions, "NATIVE_MEDIA_TYPE");
     bool bWriteCRSIfWGS84 = true;
     bool bFoundNameInNativeData = false;
-    if( pszNativeMediaType &&
+    if( pszNativeData && pszNativeMediaType &&
         EQUAL(pszNativeMediaType, "application/vnd.geo+json") )
     {
         json_object *poObj = NULL;
diff --git a/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp b/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp
index 6941e9d..5200694 100644
--- a/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp
+++ b/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp
@@ -33,7 +33,7 @@
 #include <json.h> // JSON-C
 #include <ogr_api.h>
 
-CPL_CVSID("$Id: ogrgeojsonreader.cpp 37858 2017-03-29 10:19:55Z rouault $");
+CPL_CVSID("$Id: ogrgeojsonreader.cpp 38123 2017-04-23 11:20:44Z rouault $");
 
 /************************************************************************/
 /*                           OGRGeoJSONReader                           */
@@ -149,11 +149,7 @@ void OGRGeoJSONReader::ReadLayer( OGRGeoJSONDataSource* poDS,
     {
         // If there is none defined, we use 4326.
         poSRS = new OGRSpatialReference();
-        if( OGRERR_NONE != poSRS->importFromEPSG( 4326 ) )
-        {
-            delete poSRS;
-            poSRS = NULL;
-        }
+        poSRS->SetFromUserInput(SRS_WKT_WGS84);
     }
 
     CPLErrorReset();
@@ -237,13 +233,7 @@ void OGRGeoJSONReader::ReadLayer( OGRGeoJSONDataSource* poDS,
     else if( GeoJSONObject::eFeature == objType )
     {
         OGRFeature* poFeature = ReadFeature( poLayer, poObj );
-        if( !AddFeature( poLayer, poFeature ) )
-        {
-            CPLDebug( "GeoJSON", "Translation of single feature failed." );
-
-            delete poLayer;
-            return;
-        }
+        AddFeature( poLayer, poFeature );
     }
 /* -------------------------------------------------------------------- */
 /*      Translate multi-feature FeatureCollection object.               */
@@ -514,7 +504,7 @@ bool OGRGeoJSONReader::GenerateLayerDefn( OGRGeoJSONLayer* poLayer,
 }
 
 /************************************************************************/
-/*                     OGRGeoJSONReaderAddNewField()                    */
+/*                     OGRGeoJSONReaderAddOrUpdateField()               */
 /************************************************************************/
 
 void OGRGeoJSONReaderAddOrUpdateField(
@@ -590,8 +580,6 @@ void OGRGeoJSONReaderAddOrUpdateField(
                 GeoJSONPropertyToFieldType( poVal, eSubType, bArrayAsString );
             poFDefn->SetSubType(OFSTNone);
             poFDefn->SetType(eNewType);
-            if( eSubType == OFSTBoolean )
-                poFDefn->SetWidth(1);
             if( poFDefn->GetType() == OFTString )
             {
                 poFDefn->SetType(GeoJSONStringPropertyToFieldType( poVal ));
@@ -611,10 +599,26 @@ void OGRGeoJSONReaderAddOrUpdateField(
                 poFDefn->SetSubType(OFSTNone);
             }
             else if( eNewType == OFTInteger64 || eNewType == OFTReal ||
-                     eNewType == OFTString )
+                     eNewType == OFTString ||
+                     eNewType == OFTInteger64List || eNewType == OFTRealList ||
+                     eNewType == OFTStringList )
+            {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(eNewType);
+            }
+            else if( eNewType == OFTIntegerList )
             {
+                if( poFDefn->GetSubType() == OFSTBoolean &&
+                    eSubType != OFSTBoolean )
+                {
+                    poFDefn->SetSubType(OFSTNone);
+                }
                 poFDefn->SetType(eNewType);
+            }
+            else if( eNewType != OFTInteger )
+            {
                 poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(OFTString);
             }
         }
         else if( eType == OFTInteger64 )
@@ -624,18 +628,114 @@ void OGRGeoJSONReaderAddOrUpdateField(
                 GeoJSONPropertyToFieldType( poVal, eSubType, bArrayAsString );
             if( eNewType == OFTReal || eNewType == OFTString )
             {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(eNewType);
+            }
+            else if( eNewType == OFTIntegerList ||
+                     eNewType == OFTInteger64List )
+            {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(OFTInteger64List);
+            }
+            else if( eNewType == OFTRealList || eNewType == OFTStringList )
+            {
+                poFDefn->SetSubType(OFSTNone);
                 poFDefn->SetType(eNewType);
+            }
+            else if( eNewType != OFTInteger && eNewType != OFTInteger64 )
+            {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(OFTString);
+            }
+        }
+        else if( eType == OFTReal )
+        {
+            OGRFieldSubType eSubType;
+            const OGRFieldType eNewType =
+                GeoJSONPropertyToFieldType( poVal, eSubType, bArrayAsString );
+            if(  eNewType == OFTIntegerList ||
+                 eNewType == OFTInteger64List || eNewType == OFTRealList )
+            {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(OFTRealList);
+            }
+            else if( eNewType == OFTStringList )
+            {
                 poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(OFTStringList);
             }
+            else if( eNewType != OFTInteger && eNewType != OFTInteger64 &&
+                     eNewType != OFTReal )
+            {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(OFTString);
+            }
+        }
+        else if( eType == OFTString )
+        {
+            OGRFieldSubType eSubType;
+            const OGRFieldType eNewType =
+                GeoJSONPropertyToFieldType( poVal, eSubType, bArrayAsString );
+            if( eNewType == OFTStringList )
+                poFDefn->SetType(OFTStringList);
         }
-        else if( eType == OFTIntegerList || eType == OFTInteger64List )
+        else if( eType == OFTIntegerList )
         {
             OGRFieldSubType eSubType;
             OGRFieldType eNewType =
                 GeoJSONPropertyToFieldType( poVal, eSubType, bArrayAsString );
             if( eNewType == OFTInteger64List || eNewType == OFTRealList ||
                 eNewType == OFTStringList )
+            {
+                poFDefn->SetSubType(OFSTNone);
                 poFDefn->SetType(eNewType);
+            }
+            else if( eNewType == OFTInteger64 )
+            {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(OFTInteger64List);
+            }
+            else if( eNewType == OFTReal )
+            {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(OFTRealList);
+            }
+            else if( eNewType == OFTInteger || eNewType == OFTIntegerList )
+            {
+                if( poFDefn->GetSubType() == OFSTBoolean &&
+                    eSubType != OFSTBoolean )
+                {
+                    poFDefn->SetSubType(OFSTNone);
+                }
+            }
+            else if( eNewType != OFTInteger )
+            {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(OFTString);
+            }
+        }
+        else if( eType == OFTInteger64List )
+        {
+            OGRFieldSubType eSubType;
+            OGRFieldType eNewType =
+                GeoJSONPropertyToFieldType( poVal, eSubType, bArrayAsString );
+            if( eNewType == OFTInteger64List || eNewType == OFTRealList ||
+                eNewType == OFTStringList )
+            {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(eNewType);
+            }
+            else if( eNewType == OFTReal )
+            {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(OFTRealList);
+            }
+            else if( eNewType != OFTInteger && eNewType != OFTInteger64 &&
+                     eNewType != OFTIntegerList )
+            {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(OFTString);
+            }
         }
         else if( eType == OFTRealList )
         {
@@ -643,7 +743,17 @@ void OGRGeoJSONReaderAddOrUpdateField(
             const OGRFieldType eNewType =
                 GeoJSONPropertyToFieldType( poVal, eSubType, bArrayAsString );
             if( eNewType == OFTStringList )
+            {
+                poFDefn->SetSubType(OFSTNone);
                 poFDefn->SetType(eNewType);
+            }
+            else if( eNewType != OFTInteger && eNewType != OFTInteger64 &&
+                     eNewType != OFTReal && eNewType != OFTIntegerList &&
+                     eNewType != OFTInteger64List && eNewType != OFTRealList )
+            {
+                poFDefn->SetSubType(OFSTNone);
+                poFDefn->SetType(OFTString);
+            }
         }
         else if( eType == OFTDate || eType == OFTTime || eType == OFTDateTime )
         {
@@ -654,6 +764,7 @@ void OGRGeoJSONReaderAddOrUpdateField(
                 eNewType = GeoJSONStringPropertyToFieldType( poVal );
             if( eType != eNewType )
             {
+                poFDefn->SetSubType(OFSTNone);
                 if( eType == OFTDate && eNewType == OFTDateTime )
                 {
                     poFDefn->SetType(OFTDateTime);
@@ -664,6 +775,8 @@ void OGRGeoJSONReaderAddOrUpdateField(
                 }
             }
         }
+
+        poFDefn->SetWidth( poFDefn->GetSubType() == OFSTBoolean ? 1 : 0 );
     }
 }
 
@@ -1006,7 +1119,8 @@ void OGRGeoJSONReaderSetField( OGRLayer* poLayer,
     }
     else if( OFTIntegerList == eType )
     {
-        if( json_object_get_type(poVal) == json_type_array )
+        const enum json_type eJSonType(json_object_get_type(poVal));
+        if( eJSonType == json_type_array )
         {
             const int nLength = json_object_array_length(poVal);
             int* panVal = static_cast<int *>(CPLMalloc(sizeof(int) * nLength));
@@ -1018,10 +1132,16 @@ void OGRGeoJSONReaderSetField( OGRLayer* poLayer,
             poFeature->SetField( nField, nLength, panVal );
             CPLFree(panVal);
         }
+        else if ( eJSonType == json_type_boolean ||
+                  eJSonType == json_type_int )
+        {
+            poFeature->SetField( nField, json_object_get_int(poVal) );
+        }
     }
     else if( OFTInteger64List == eType )
     {
-        if( json_object_get_type(poVal) == json_type_array )
+        const enum json_type eJSonType(json_object_get_type(poVal));
+        if( eJSonType == json_type_array )
         {
             const int nLength = json_object_array_length(poVal);
             GIntBig* panVal =
@@ -1034,10 +1154,17 @@ void OGRGeoJSONReaderSetField( OGRLayer* poLayer,
             poFeature->SetField( nField, nLength, panVal );
             CPLFree(panVal);
         }
+        else if ( eJSonType == json_type_boolean ||
+                  eJSonType == json_type_int )
+        {
+            poFeature->SetField( nField,
+                        static_cast<GIntBig>(json_object_get_int64(poVal)));
+        }
     }
     else if( OFTRealList == eType )
     {
-        if( json_object_get_type(poVal) == json_type_array )
+        const enum json_type eJSonType(json_object_get_type(poVal));
+        if( eJSonType == json_type_array )
         {
             const int nLength = json_object_array_length(poVal);
             double* padfVal =
@@ -1050,10 +1177,16 @@ void OGRGeoJSONReaderSetField( OGRLayer* poLayer,
             poFeature->SetField( nField, nLength, padfVal );
             CPLFree(padfVal);
         }
+        else if ( eJSonType == json_type_boolean ||
+                  eJSonType == json_type_int || eJSonType == json_type_double )
+        {
+            poFeature->SetField( nField, json_object_get_double(poVal) );
+        }
     }
     else if( OFTStringList == eType )
     {
-        if( json_object_get_type(poVal) == json_type_array )
+        const enum json_type eJSonType(json_object_get_type(poVal));
+        if( eJSonType == json_type_array )
         {
             const int nLength = json_object_array_length(poVal);
             char** papszVal = (char**)CPLMalloc(sizeof(char*) * (nLength+1));
@@ -1070,6 +1203,10 @@ void OGRGeoJSONReaderSetField( OGRLayer* poLayer,
             poFeature->SetField( nField, papszVal );
             CSLDestroy(papszVal);
         }
+        else
+        {
+            poFeature->SetField( nField, json_object_get_string(poVal) );
+        }
     }
     else
     {
@@ -1934,7 +2071,7 @@ OGRGeometryCollection* OGRGeoJSONReadGeometryCollection( json_object* poObj )
 }
 
 /************************************************************************/
-/*                           OGR_G_ExportToJson                         */
+/*                       OGR_G_CreateGeometryFromJson                   */
 /************************************************************************/
 
 /** Create a OGR geometry from a GeoJSON geometry object */
@@ -1999,13 +2136,14 @@ bool OGRJSonParse( const char* pszText, json_object** ppoObj,
     if( ppoObj == NULL )
         return false;
     json_tokener* jstok = json_tokener_new();
-    *ppoObj = json_tokener_parse_ex(jstok, pszText, -1);
+    const int nLen = pszText == NULL ? 0 : static_cast<int>(strlen(pszText));
+    *ppoObj = json_tokener_parse_ex(jstok, pszText, nLen);
     if( jstok->err != json_tokener_success)
     {
         if( bVerboseError )
         {
             CPLError(CE_Failure, CPLE_AppDefined,
-                     "GeoJSON parsing error: %s (at offset %d)",
+                     "JSON parsing error: %s (at offset %d)",
                      json_tokener_error_desc(jstok->err), jstok->char_offset);
         }
 
diff --git a/ogr/ogrsf_frmts/geojson/ogrtopojsonreader.cpp b/ogr/ogrsf_frmts/geojson/ogrtopojsonreader.cpp
index 76629df..d164094 100644
--- a/ogr/ogrsf_frmts/geojson/ogrtopojsonreader.cpp
+++ b/ogr/ogrsf_frmts/geojson/ogrtopojsonreader.cpp
@@ -32,7 +32,7 @@
 #include <json.h>  // JSON-C
 #include <ogr_api.h>
 
-CPL_CVSID("$Id: ogrtopojsonreader.cpp 37269 2017-02-02 12:02:03Z rouault $");
+CPL_CVSID("$Id: ogrtopojsonreader.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 /************************************************************************/
 /*                          OGRTopoJSONReader()                         */
@@ -60,26 +60,15 @@ OGRTopoJSONReader::~OGRTopoJSONReader()
 
 OGRErr OGRTopoJSONReader::Parse( const char* pszText )
 {
-    if( NULL != pszText )
+    json_object *jsobj = NULL;
+    if( NULL != pszText && !OGRJSonParse(pszText, &jsobj, true) )
     {
-        json_tokener *jstok = json_tokener_new();
-        json_object *jsobj = json_tokener_parse_ex(jstok, pszText, -1);
-        if( jstok->err != json_tokener_success)
-        {
-            CPLError( CE_Failure, CPLE_AppDefined,
-                      "TopoJSON parsing error: %s (at offset %d)",
-                      json_tokener_error_desc(jstok->err), jstok->char_offset );
-
-            json_tokener_free(jstok);
-            return OGRERR_CORRUPT_DATA;
-        }
-        json_tokener_free(jstok);
-
-        // JSON tree is shared for while lifetime of the reader object
-        // and will be released in the destructor.
-        poGJObject_ = jsobj;
+        return OGRERR_CORRUPT_DATA;
     }
 
+    // JSON tree is shared for while lifetime of the reader object
+    // and will be released in the destructor.
+    poGJObject_ = jsobj;
     return OGRERR_NONE;
 }
 
diff --git a/ogr/ogrsf_frmts/gmlas/drv_gmlas.html b/ogr/ogrsf_frmts/gmlas/drv_gmlas.html
index 9e2438e..3cbb8ea 100644
--- a/ogr/ogrsf_frmts/gmlas/drv_gmlas.html
+++ b/ogr/ogrsf_frmts/gmlas/drv_gmlas.html
@@ -58,6 +58,15 @@ well as content required by the schema and absent from the document.</p>
 <p>Consult the <a href="drv_gmlas_mapping_examples.html">GMLAS mapping examples</a>
 page for more details.</p>
 
+<p>By default in the configuration, swe:DataRecord and swe:DataArray elements
+from the Sensor Web Enablement (SWE) Common Data Model namespace will receive
+a special processing, so they are mapped more naturally to OGR concepts. The
+swe:field elements will be mapped as OGR fields, and the swe:values element of
+a swe:DataArray will be parsed into OGR features in a dedicated layer for each
+swe:DataArray. Note that those conveniency exposure is for read-only purpose.
+When using the write side of the driver, only the content of the general
+mapping mechanisms will be used.</p>
+
 <h2>Metadata layers</h2>
 
 <p>Three special layers "_ogr_fields_metadata", "_ogr_layers_metadata",
@@ -346,6 +355,9 @@ but with limited support for complex features<br/></li>
 
 <p>Initial implementation has been funded by the European Union's Earth observation programme
 Copernicus, as part of the tasks delegated to the European Environment Agency.</p>
+<p>Development of special processing of some Sensor Web Enablement (SWE)
+Common Data Model swe:DataRecord and swe:DataArray constructs has been funded
+by Bureau des Recherches Géologiques et Minières (BRGM).</p>
 
 </body>
 </html>
diff --git a/ogr/ogrsf_frmts/gmlas/drv_gmlas_mapping_examples.html b/ogr/ogrsf_frmts/gmlas/drv_gmlas_mapping_examples.html
index c5403a8..3dca4bb 100644
--- a/ogr/ogrsf_frmts/gmlas/drv_gmlas_mapping_examples.html
+++ b/ogr/ogrsf_frmts/gmlas/drv_gmlas_mapping_examples.html
@@ -315,6 +315,85 @@ OGRFeature(MyFeature2_names_name_name):1
 
 </table>
 
+<h2>swe:DataArray</h2>
+
+The following snippet
+
+<pre>
+    <swe:DataArray>
+        <swe:elementCount>
+            <swe:Count>
+                    <swe:value>2</swe:value>
+            </swe:Count>
+        </swe:elementCount>
+        <swe:elementType name="Components">
+            <swe:DataRecord>
+                    <swe:field name="myTime">
+                        <swe:Time definition="http://www.opengis.net/def/property/OGC/0/SamplingTime">
+                                <swe:uom xlink:href="http://www.opengis.net/def/uom/ISO-8601/0/Gregorian"/>
+                        </swe:Time>
+                    </swe:field>
+                    <swe:field name="myCategory">
+                        <swe:Category definition="http://dd.eionet.europa.eu/vocabulary/aq/observationverification"/>
+                    </swe:field>
+                        <swe:field name="myQuantity">
+                        <swe:Quantity definition="http://dd.eionet.europa.eu/vocabulary/aq/primaryObservation/hour">
+                                <swe:uom xlink:href="http://dd.eionet.europa.eu/vocabulary/uom/concentration/ug.m-3"/>
+                        </swe:Quantity>
+                    </swe:field>
+                    <swe:field name="myCount">
+                        <swe:Count definition="http://"/>
+                    </swe:field>
+                        <swe:field name="myText">
+                        <swe:Text definition="http://"/>
+                    </swe:field>
+                        <swe:field name="myBoolean">
+                        <swe:Boolean definition="http://"/>
+                    </swe:field>
+            </swe:DataRecord>
+        </swe:elementType>
+        <swe:encoding>
+                <swe:TextEncoding decimalSeparator="." blockSeparator="@@" tokenSeparator=","/>
+        </swe:encoding>
+        <swe:values>2016-09-01T00:00:00+01:00,1,2.34,3,foo,true@@2017-09-01T00:00:00,2,3.45</swe:values>
+    </swe:DataArray>
+</pre>
+
+will receive a special processing to be mapped into a dedicated layer:
+
+<pre>
+
+Layer name: dataarray_1_components
+Geometry: None
+Feature Count: 2
+Layer SRS WKT:
+(unknown)
+parent_ogr_pkid: String (0.0) NOT NULL
+mytime: DateTime (0.0)
+mycategory: String (0.0)
+myquantity: Real (0.0)
+mycount: Integer (0.0)
+mytext: String (0.0)
+myboolean: Integer(Boolean) (0.0)
+OGRFeature(dataarray_1_components):1
+  parent_ogr_pkid (String) = BAE8440FC4563A80D2AB1860A47AA0A3_DataArray_1
+  mytime (DateTime) = 2016/09/01 00:00:00+01
+  mycategory (String) = 1
+  myquantity (Real) = 2.34
+  mycount (Integer) = 3
+  mytext (String) = foo
+  myboolean (Integer(Boolean)) = 1
+
+OGRFeature(dataarray_1_components):2
+  parent_ogr_pkid (String) = BAE8440FC4563A80D2AB1860A47AA0A3_DataArray_1
+  mytime (DateTime) = 2017/09/01 00:00:00
+  mycategory (String) = 2
+  myquantity (Real) = 3.45
+
+
+
+</pre>
+
 <h2>See Also</h2>
 
 <ul>
diff --git a/ogr/ogrsf_frmts/gmlas/drv_gmlas_metadata_layers.html b/ogr/ogrsf_frmts/gmlas/drv_gmlas_metadata_layers.html
index fc15e8c..e91fd29 100644
--- a/ogr/ogrsf_frmts/gmlas/drv_gmlas_metadata_layers.html
+++ b/ogr/ogrsf_frmts/gmlas/drv_gmlas_metadata_layers.html
@@ -59,7 +59,7 @@ Only set when field_max_occurs is not 0 or 1.</td></tr>
 <tr><td>field_fixed_value</td><td>Fixed value of the field, or null</td></tr>
 <tr><td>field_category</td><td>Category of the field. May be REGULAR,
 PATH_TO_CHILD_ELEMENT_NO_LINK, PATH_TO_CHILD_ELEMENT_WITH_LINK,
-PATH_TO_CHILD_ELEMENT_WITH_JUNCTION_TABLE or GROUP. May be null for a field
+PATH_TO_CHILD_ELEMENT_WITH_JUNCTION_TABLE, GROUP or SWE_FIELD. May be null for a field
 generated by OGR.</td></tr>
 <tr><td>field_related_layer</td><td>Name of the child layer for
 field_category != REGULAR</td></tr>
@@ -89,6 +89,8 @@ the link between the parent and child layer is done through a junction table
 is not instantiated as a OGR field of the layer 'layer_name'. It is merely there
 to declare the relationship between the parent and child layers. This is when
 a layer uses XML schema group constructs with repeated cardinality.</li>
+<li>SWE_FIELD: A field derived from special processing of swe:DataRecord or
+swe:DataArray elements.</li>
 </ul>
 
 <h3>_ogr_layers_metadata layer</h3>
@@ -105,13 +107,14 @@ a layer uses XML schema group constructs with repeated cardinality.</li>
 <tr><td>layer_xpath</td><td>XPath of the element that is used as the root
 element for the layer. May be suffixed with ";extra=XXXX" for group constructs
 or repeated sequences of repeated elements, so as to distinguish for the XPath
-of their parent element. Will be null for junction tables.</td></tr>
+of their parent element. Will be null for junction tables or SWE_DATA_ARRAY
+layers.</td></tr>
 <tr><td>layer_category</td><td>Category of the layer. One of TOP_LEVEL_ELEMENT,
-NESTED_ELEMENT or JUNCTION_TABLE</td></tr>
+NESTED_ELEMENT, JUNCTION_TABLE or SWE_DATA_ARRAY</td></tr>
 <tr><td>layer_pkid_name</td><td>Name of the primary key field. This is the
 text attribute that uniquely identified a feature (in its layer). This is
 the XML attribute/name of type xs:ID when it exists, otherwise a "ogr_pkid"
-field is automatically created.</td></tr>
+field is automatically created. Will be null for SWE_DATA_ARRAY layers.</td></tr>
 <tr><td>layer_parent_pkid_name</td><td>Name of the field that is a foreign key
 to the parent layer of this layer. Only set for a NESTED_ELEMENT layer.</td></tr>
 <tr><td>layer_documentation</td><td>Documentation from the schema.</td></tr>
@@ -133,7 +136,8 @@ to the parent layer of this layer. Only set for a NESTED_ELEMENT layer.</td></tr
 parent to the child. Will be null when the child layer is due to group constructs
 or repeated sequences of repeated elements of the parent.</td></tr>
 <tr><td>child_layer</td><td>Name of the child layer</td></tr>
-<tr><td>child_pkid</td><td>Name of the primary key of the child layer</td></tr>
+<tr><td>child_pkid</td><td>Name of the primary key of the child layer. Will
+be null for SWE_DATA_ARRAY layers</td></tr>
 </table>
 
 <h3>_ogr_other_metadata layer</h3>
diff --git a/ogr/ogrsf_frmts/gmlas/ogr_gmlas.h b/ogr/ogrsf_frmts/gmlas/ogr_gmlas.h
index 907ba0f..2acb84c 100644
--- a/ogr/ogrsf_frmts/gmlas/ogr_gmlas.h
+++ b/ogr/ogrsf_frmts/gmlas/ogr_gmlas.h
@@ -374,6 +374,9 @@ class GMLASConfiguration
         /** If and when activate SWE special processings */
         SWEActivationMode m_eSWEActivationMode;
 
+        /** If enabling swe:DataRecord parsing */
+        bool m_bSWEProcessDataRecord;
+
         /** If enabling swe:DataArray parsing */
         bool m_bSWEProcessDataArray;
 
@@ -1143,6 +1146,7 @@ class OGRGMLASLayer: public OGRLayer
         OGRGMLASDataSource            *m_poDS;
         GMLASFeatureClass              m_oFC;
         bool                           m_bLayerDefnFinalized;
+        int                            m_nMaxFieldIndex;
         OGRFeatureDefn                *m_poFeatureDefn;
 
         /** Map from XPath to corresponding field index in OGR layer
@@ -1173,6 +1177,8 @@ class OGRGMLASLayer: public OGRLayer
         /** OGR field index of the field that points to the parent ID */
         int                            m_nParentIDFieldIdx;
 
+        std::map<CPLString, CPLString> m_oMapSWEFieldToOGRFieldName;
+
         OGRFeature*                    GetNextRawFeature();
 
         bool                           InitReader();
@@ -1197,7 +1203,14 @@ class OGRGMLASLayer: public OGRLayer
         void SetDataSource(OGRGMLASDataSource* poDS) { m_poDS = poDS; }
 
         void PostInit(bool bIncludeGeometryXML);
-        void ProcessDataRecord(CPLXMLNode* psDataRecord);
+        void ProcessDataRecordCreateFields(CPLXMLNode* psDataRecord,
+                                const std::vector<OGRFeature*>& apoFeatures,
+                                OGRLayer* poFieldsMetadataLayer);
+        void ProcessDataRecordFillFeature(CPLXMLNode* psDataRecord,
+                                          OGRFeature* poFeature);
+        void ProcessDataRecordOfDataArrayCreateFields(OGRGMLASLayer* poParentLayer,
+                                                      CPLXMLNode* psDataRecord,
+                                                      OGRLayer* poFieldsMetadataLayer);
         void CreateCompoundFoldedMappings();
 
         const GMLASFeatureClass& GetFeatureClass() const { return m_oFC; }
@@ -1399,9 +1412,22 @@ class GMLASReader : public DefaultHandler
         /** Whether to process swe:DataArray in a special way */
         bool                        m_bProcessSWEDataArray;
 
+        /** Whether to process swe:DataArray in a special way */
+        bool                        m_bProcessSWEDataRecord;
+
         /** Depth level of the swe:DataArray element */
         int                         m_nSWEDataArrayLevel;
 
+        /** Field name to which the DataArray belongs to */
+        CPLString                   m_osSWEDataArrayParentField;
+
+        /** Depth level of the swe:DataRecord element */
+        int                         m_nSWEDataRecordLevel;
+
+        OGRLayer                   *m_poFieldsMetadataLayer;
+        OGRLayer                   *m_poLayersMetadataLayer;
+        OGRLayer                   *m_poRelationshipsLayer;
+
         /** Base unique identifier */
         CPLString                      m_osHash;
 
@@ -1451,6 +1477,7 @@ class GMLASReader : public DefaultHandler
         void        AttachAsLastChild(CPLXMLNode* psNode);
 
         void        ProcessSWEDataArray(CPLXMLNode* psRoot);
+        void        ProcessSWEDataRecord(CPLXMLNode* psRoot);
         void        ProcessGeometry(CPLXMLNode* psRoot);
 
         void        ProcessAttributes(const Attributes& attrs);
@@ -1471,7 +1498,7 @@ class GMLASReader : public DefaultHandler
                         int& nInsertFieldIdx,
                         const GMLASXLinkResolutionConf::URLSpecificResolution& oRule );
 
-        bool        FillTextContent() const { return !m_bInitialPass; }
+        bool        FillTextContent() const { return !m_bInitialPass && m_nCurFieldIdx >=0; }
 
     public:
                         GMLASReader(GMLASXSDCache& oCache,
@@ -1536,6 +1563,9 @@ class GMLASReader : public DefaultHandler
                           bool bRemoveUnusedLayers,
                           bool bRemoveUnusedFields,
                           bool bProcessSWEDataArray,
+                          OGRLayer* poFieldsMetadataLayer,
+                          OGRLayer* poLayersMetadataLayer,
+                          OGRLayer* poRelationshipsLayer,
                           std::set<CPLString>& aoSetRemovedLayerNames);
 
         static bool LoadXSDInParser( SAX2XMLReader* poParser,
@@ -1548,6 +1578,7 @@ class GMLASReader : public DefaultHandler
                                      bool bHandleMultipleImports );
 
         void SetSWEDataArrayLayers( const std::vector<OGRGMLASLayer*>& ar );
+        void SetProcessDataRecord(bool b) { m_bProcessSWEDataRecord = b; }
         const std::vector<OGRGMLASLayer*>& GetSWEDataArrayLayers() const
             { return m_apoSWEDataArrayLayers; }
 };
diff --git a/ogr/ogrsf_frmts/gmlas/ogr_gmlas_consts.h b/ogr/ogrsf_frmts/gmlas/ogr_gmlas_consts.h
index 9f1014d..00d101e 100644
--- a/ogr/ogrsf_frmts/gmlas/ogr_gmlas_consts.h
+++ b/ogr/ogrsf_frmts/gmlas/ogr_gmlas_consts.h
@@ -63,6 +63,7 @@ namespace GMLASConstants
     BOOL_CONST(VALIDATE_DEFAULT, false);
     BOOL_CONST(FAIL_IF_VALIDATION_ERROR_DEFAULT, false);
     BOOL_CONST(EXPOSE_METADATA_LAYERS_DEFAULT, false);
+    BOOL_CONST(SWE_PROCESS_DATA_RECORD_DEFAULT, true);
     BOOL_CONST(SWE_PROCESS_DATA_ARRAY_DEFAULT, true);
     BOOL_CONST(WARN_IF_EXCLUDED_XPATH_FOUND_DEFAULT, true);
     BOOL_CONST(CASE_INSENSITIVE_IDENTIFIER_DEFAULT, true);
@@ -196,6 +197,7 @@ namespace GMLASConstants
     STRING_CONST(szTOP_LEVEL_ELEMENT, "TOP_LEVEL_ELEMENT");
     STRING_CONST(szNESTED_ELEMENT, "NESTED_ELEMENT");
     STRING_CONST(szJUNCTION_TABLE, "JUNCTION_TABLE");
+    STRING_CONST(szSWE_DATA_ARRAY, "SWE_DATA_ARRAY");
 
 // Values of field_category
     STRING_CONST(szREGULAR, "REGULAR");
@@ -206,6 +208,7 @@ namespace GMLASConstants
     STRING_CONST(szPATH_TO_CHILD_ELEMENT_WITH_JUNCTION_TABLE,
                                     "PATH_TO_CHILD_ELEMENT_WITH_JUNCTION_TABLE");
     STRING_CONST(szGROUP, "GROUP");
+    STRING_CONST(szSWE_FIELD, "SWE_FIELD");
 
     STRING_CONST(szGMLAS_PREFIX, "GMLAS:");
     STRING_CONST(szDEFAULT_CONF_FILENAME, "gmlasconf.xml");
diff --git a/ogr/ogrsf_frmts/gmlas/ogrgmlasconf.cpp b/ogr/ogrsf_frmts/gmlas/ogrgmlasconf.cpp
index a401cc1..a9ab5f7 100644
--- a/ogr/ogrsf_frmts/gmlas/ogrgmlasconf.cpp
+++ b/ogr/ogrsf_frmts/gmlas/ogrgmlasconf.cpp
@@ -39,7 +39,7 @@
 
 #include <algorithm>
 
-CPL_CVSID("$Id: ogrgmlasconf.cpp 37974 2017-04-12 16:16:55Z rouault $");
+CPL_CVSID("$Id: ogrgmlasconf.cpp 38073 2017-04-20 17:00:47Z rouault $");
 
 /************************************************************************/
 /*                          GMLASConfiguration()                        */
@@ -65,6 +65,7 @@ GMLASConfiguration::GMLASConfiguration()
     , m_bFailIfValidationError(FAIL_IF_VALIDATION_ERROR_DEFAULT)
     , m_bExposeMetadataLayers(WARN_IF_EXCLUDED_XPATH_FOUND_DEFAULT)
     , m_eSWEActivationMode(SWE_ACTIVATE_IF_NAMESPACE_FOUND)
+    , m_bSWEProcessDataRecord(SWE_PROCESS_DATA_RECORD_DEFAULT)
     , m_bSWEProcessDataArray(SWE_PROCESS_DATA_ARRAY_DEFAULT)
     , m_nIndentSize(INDENT_SIZE_DEFAULT)
     , m_osSRSNameFormat(szSRSNAME_DEFAULT)
@@ -421,6 +422,9 @@ bool GMLASConfiguration::Load(const char* pszFilename)
         m_eSWEActivationMode = SWE_ACTIVATE_TRUE;
     else
         m_eSWEActivationMode = SWE_ACTIVATE_FALSE;
+    m_bSWEProcessDataRecord = CPLTestBool(CPLGetXMLValue( psRoot,
+        "=Configuration.LayerBuildingRules.SWEProcessing.ProcessDataRecord",
+        "true" ));
     m_bSWEProcessDataArray = CPLTestBool(CPLGetXMLValue( psRoot,
         "=Configuration.LayerBuildingRules.SWEProcessing.ProcessDataArray",
         "true" ));
diff --git a/ogr/ogrsf_frmts/gmlas/ogrgmlasdatasource.cpp b/ogr/ogrsf_frmts/gmlas/ogrgmlasdatasource.cpp
index 92f9fd3..7ca70b5 100644
--- a/ogr/ogrsf_frmts/gmlas/ogrgmlasdatasource.cpp
+++ b/ogr/ogrsf_frmts/gmlas/ogrgmlasdatasource.cpp
@@ -36,7 +36,7 @@
 
 #include <algorithm>
 
-CPL_CVSID("$Id: ogrgmlasdatasource.cpp 37974 2017-04-12 16:16:55Z rouault $");
+CPL_CVSID("$Id: ogrgmlasdatasource.cpp 38073 2017-04-20 17:00:47Z rouault $");
 
 /************************************************************************/
 /*                          OGRGMLASDataSource()                        */
@@ -972,7 +972,9 @@ bool OGRGMLASDataSource::Open(GDALOpenInfo* poOpenInfo)
     m_oXLinkResolver.SetConf( m_oConf.m_oXLinkResolution );
     m_oXLinkResolver.SetRefreshMode( bRefreshCache );
 
-    if( m_bValidate || m_bRemoveUnusedLayers || m_bFoundSWE )
+    if( m_bValidate || m_bRemoveUnusedLayers ||
+        (m_bFoundSWE && (m_oConf.m_bSWEProcessDataRecord ||
+                         m_oConf.m_bSWEProcessDataArray)) )
     {
         CPLErrorReset();
         RunFirstPassIfNeeded( NULL, NULL, NULL );
@@ -1245,6 +1247,7 @@ bool OGRGMLASDataSource::RunFirstPassIfNeeded( GMLASReader* poReader,
         {
             poReader->SetMapSRSNameToInvertedAxis(m_oMapSRSNameToInvertedAxis);
             poReader->SetMapGeomFieldDefnToSRSName(m_oMapGeomFieldDefnToSRSName);
+            poReader->SetProcessDataRecord(m_bFoundSWE && m_oConf.m_bSWEProcessDataRecord);
             poReader->SetSWEDataArrayLayers(m_apoSWEDataArrayLayers);
         }
         return true;
@@ -1268,7 +1271,9 @@ bool OGRGMLASDataSource::RunFirstPassIfNeeded( GMLASReader* poReader,
     const bool bHasURLSpecificRules =
                 !m_oXLinkResolver.GetConf().m_aoURLSpecificRules.empty();
     if( bHasGeomFields || m_bValidate || m_bRemoveUnusedLayers ||
-        m_bRemoveUnusedFields || bHasURLSpecificRules || m_bFoundSWE )
+        m_bRemoveUnusedFields || bHasURLSpecificRules ||
+        (m_bFoundSWE && (m_oConf.m_bSWEProcessDataRecord ||
+                         m_oConf.m_bSWEProcessDataArray)) )
     {
         bool bJustOpenedFiled =false;
         VSILFILE* fp = NULL;
@@ -1296,6 +1301,9 @@ bool OGRGMLASDataSource::RunFirstPassIfNeeded( GMLASReader* poReader,
                                  m_bSchemaFullChecking,
                                  m_bHandleMultipleImports );
 
+        poReaderFirstPass->SetProcessDataRecord(
+            m_bFoundSWE && m_oConf.m_bSWEProcessDataRecord);
+
         poReaderFirstPass->SetFileSize( m_nFileSize );
 
         poReaderFirstPass->SetMapIgnoredXPathToWarn(
@@ -1310,6 +1318,9 @@ bool OGRGMLASDataSource::RunFirstPassIfNeeded( GMLASReader* poReader,
             m_bRemoveUnusedLayers,
             m_bRemoveUnusedFields,
             m_bFoundSWE && m_oConf.m_bSWEProcessDataArray,
+            m_poFieldsMetadataLayer,
+            m_poLayersMetadataLayer,
+            m_poRelationshipsLayer,
             aoSetRemovedLayerNames);
 
         const std::vector<OGRGMLASLayer*>& apoSWEDataArrayLayers =
@@ -1401,6 +1412,7 @@ bool OGRGMLASDataSource::RunFirstPassIfNeeded( GMLASReader* poReader,
         {
             poReader->SetMapSRSNameToInvertedAxis(m_oMapSRSNameToInvertedAxis);
             poReader->SetMapGeomFieldDefnToSRSName(m_oMapGeomFieldDefnToSRSName);
+            poReader->SetProcessDataRecord(m_bFoundSWE && m_oConf.m_bSWEProcessDataRecord);
             poReader->SetSWEDataArrayLayers(m_apoSWEDataArrayLayers);
         }
     }
diff --git a/ogr/ogrsf_frmts/gmlas/ogrgmlaslayer.cpp b/ogr/ogrsf_frmts/gmlas/ogrgmlaslayer.cpp
index 311b428..ce4eabe 100644
--- a/ogr/ogrsf_frmts/gmlas/ogrgmlaslayer.cpp
+++ b/ogr/ogrsf_frmts/gmlas/ogrgmlaslayer.cpp
@@ -30,8 +30,9 @@
 
 // Must be first for DEBUG_BOOL case
 #include "ogr_gmlas.h"
+#include "cpl_minixml.h"
 
-CPL_CVSID("$Id: ogrgmlaslayer.cpp 37972 2017-04-12 16:13:12Z rouault $");
+CPL_CVSID("$Id: ogrgmlaslayer.cpp 38073 2017-04-20 17:00:47Z rouault $");
 
 /************************************************************************/
 /*                            OGRGMLASLayer()                           */
@@ -44,6 +45,7 @@ OGRGMLASLayer::OGRGMLASLayer( OGRGMLASDataSource* poDS,
     m_poDS( poDS ),
     m_oFC( oFC ),
     m_bLayerDefnFinalized( false ),
+    m_nMaxFieldIndex( 0 ),
     m_poFeatureDefn( new OGRFeatureDefn( oFC.GetName() ) ),
     m_bEOF( false ),
     m_poReader( NULL ),
@@ -161,6 +163,7 @@ OGRGMLASLayer::OGRGMLASLayer( OGRGMLASDataSource* poDS,
 OGRGMLASLayer::OGRGMLASLayer(const char* pszLayerName) :
     m_poDS( NULL ),
     m_bLayerDefnFinalized( true ),
+    m_nMaxFieldIndex( 0 ),
     m_poFeatureDefn( new OGRFeatureDefn( pszLayerName ) ),
     m_bEOF( false ),
     m_poReader( NULL ),
@@ -178,11 +181,63 @@ OGRGMLASLayer::OGRGMLASLayer(const char* pszLayerName) :
 }
 
 /************************************************************************/
-/*                         ProcessDataRecord()                          */
+/*                        GetSWEChildAndType()                          */
 /************************************************************************/
 
-void OGRGMLASLayer::ProcessDataRecord(CPLXMLNode* psDataRecord)
+static
+CPLXMLNode* GetSWEChildAndType( CPLXMLNode* psNode,
+                                OGRFieldType& eType,
+                                OGRFieldSubType& eSubType )
 {
+    eType = OFTString;
+    eSubType = OFSTNone;
+    CPLXMLNode* psChildNode = NULL;
+    if( (psChildNode = CPLGetXMLNode(psNode, "Time")) != NULL )
+    {
+        eType = OFTDateTime;
+    }
+    else if( (psChildNode = CPLGetXMLNode(psNode, "Quantity")) != NULL )
+    {
+        eType = OFTReal;
+    }
+    else if( (psChildNode = CPLGetXMLNode(psNode, "Category")) != NULL )
+    {
+        eType = OFTString;
+    }
+    else if( (psChildNode = CPLGetXMLNode(psNode, "Count")) != NULL )
+    {
+        eType = OFTInteger;
+    }
+    else if( (psChildNode = CPLGetXMLNode(psNode, "Text")) != NULL )
+    {
+        eType = OFTString;
+    }
+    else if( (psChildNode = CPLGetXMLNode(psNode, "Boolean")) != NULL )
+    {
+        eType = OFTInteger;
+        eSubType = OFSTBoolean;
+    }
+    return psChildNode;
+}
+
+/************************************************************************/
+/*              ProcessDataRecordOfDataArrayCreateFields()               */
+/************************************************************************/
+
+void OGRGMLASLayer::ProcessDataRecordOfDataArrayCreateFields(
+                                                OGRGMLASLayer* poParentLayer,
+                                                CPLXMLNode* psDataRecord,
+                                                OGRLayer* poFieldsMetadataLayer)
+{
+    {
+        CPLString osFieldName(szPARENT_PREFIX);
+        osFieldName += poParentLayer->GetLayerDefn()->GetFieldDefn(
+                                poParentLayer->GetIDFieldIdx())->GetNameRef();
+        OGRFieldDefn oFieldDefn( osFieldName, OFTString );
+        oFieldDefn.SetNullable( false );
+        m_poFeatureDefn->AddFieldDefn(&oFieldDefn);
+    }
+
     for( CPLXMLNode* psIter = psDataRecord->psChild;
                         psIter != NULL; psIter = psIter->psNext )
     {
@@ -190,16 +245,240 @@ void OGRGMLASLayer::ProcessDataRecord(CPLXMLNode* psDataRecord)
             strcmp(psIter->pszValue, "field") == 0 )
         {
             CPLString osName = CPLGetXMLValue(psIter, "name", "");
+            osName.tolower();
             OGRFieldDefn oFieldDefn(osName, OFTString);
-            if( CPLGetXMLNode(psIter, "Time") )
+            OGRFieldType eType;
+            OGRFieldSubType eSubType;
+            CPLXMLNode* psNode = GetSWEChildAndType(psIter, eType, eSubType);
+            oFieldDefn.SetType(eType);
+            oFieldDefn.SetSubType(eSubType);
+            m_poFeatureDefn->AddFieldDefn(&oFieldDefn);
+
+            // Register field in _ogr_fields_metadata
+            OGRFeature* poFieldDescFeature =
+                        new OGRFeature(poFieldsMetadataLayer->GetLayerDefn());
+            poFieldDescFeature->SetField( szLAYER_NAME, GetName() );
+            m_nMaxFieldIndex =  m_poFeatureDefn->GetFieldCount() - 1;
+            poFieldDescFeature->SetField( szFIELD_INDEX, m_nMaxFieldIndex );
+            poFieldDescFeature->SetField( szFIELD_NAME,
+                                            oFieldDefn.GetNameRef() );
+            if( psNode )
             {
-                oFieldDefn.SetType(OFTDateTime);
+                poFieldDescFeature->SetField( szFIELD_TYPE, psNode->pszValue );
             }
-            else if( CPLGetXMLNode(psIter, "Quantity") )
+            poFieldDescFeature->SetField( szFIELD_IS_LIST, 0 );
+            poFieldDescFeature->SetField( szFIELD_MIN_OCCURS, 0 );
+            poFieldDescFeature->SetField( szFIELD_MAX_OCCURS, 1 );
+            poFieldDescFeature->SetField( szFIELD_CATEGORY, szSWE_FIELD );
+            if( psNode )
             {
-                oFieldDefn.SetType(OFTReal);
+                char* pszXML = CPLSerializeXMLTree(psNode);
+                poFieldDescFeature->SetField( szFIELD_DOCUMENTATION, pszXML);
+                CPLFree(pszXML);
+            }
+            CPL_IGNORE_RET_VAL(
+                poFieldsMetadataLayer->CreateFeature(poFieldDescFeature));
+            delete poFieldDescFeature;
+        }
+    }
+}
+
+/************************************************************************/
+/*                ProcessDataRecordCreateFields()                       */
+/************************************************************************/
+
+void OGRGMLASLayer::ProcessDataRecordCreateFields(
+                                CPLXMLNode* psDataRecord,
+                                const std::vector<OGRFeature*>& apoFeatures,
+                                OGRLayer* poFieldsMetadataLayer)
+{
+    for( CPLXMLNode* psIter = psDataRecord->psChild;
+                        psIter != NULL; psIter = psIter->psNext )
+    {
+        if( psIter->eType == CXT_Element &&
+            strcmp(psIter->pszValue, "field") == 0 )
+        {
+            CPLString osName = CPLGetXMLValue(psIter, "name", "");
+            osName = osName.tolower();
+            OGRFieldDefn oFieldDefn(osName, OFTString);
+            OGRFieldType eType;
+            OGRFieldSubType eSubType;
+            CPLXMLNode* psChildNode = GetSWEChildAndType(psIter, eType, eSubType);
+            oFieldDefn.SetType(eType);
+            oFieldDefn.SetSubType(eSubType);
+            if( psChildNode != NULL &&
+                m_oMapSWEFieldToOGRFieldName.find(osName) ==
+                                        m_oMapSWEFieldToOGRFieldName.end() )
+            {
+                const int nValidFields = m_poFeatureDefn->GetFieldCount();
+
+                CPLString osSWEField(osName);
+                if( m_poFeatureDefn->GetFieldIndex(osName) >= 0 )
+                    osName = "swe_field_" + osName;
+                m_oMapSWEFieldToOGRFieldName[osSWEField] = osName;
+                oFieldDefn.SetName((osName + "_value").c_str());
+                m_poFeatureDefn->AddFieldDefn(&oFieldDefn);
+
+                // Register field in _ogr_fields_metadata
+                OGRFeature* poFieldDescFeature =
+                            new OGRFeature(poFieldsMetadataLayer->GetLayerDefn());
+                poFieldDescFeature->SetField( szLAYER_NAME, GetName() );
+                m_nMaxFieldIndex ++;
+                poFieldDescFeature->SetField( szFIELD_INDEX, m_nMaxFieldIndex);
+                poFieldDescFeature->SetField( szFIELD_NAME,
+                                                oFieldDefn.GetNameRef() );
+                if( psChildNode )
+                {
+                    poFieldDescFeature->SetField( szFIELD_TYPE, psChildNode->pszValue );
+                }
+                poFieldDescFeature->SetField( szFIELD_IS_LIST, 0 );
+                poFieldDescFeature->SetField( szFIELD_MIN_OCCURS, 0 );
+                poFieldDescFeature->SetField( szFIELD_MAX_OCCURS, 1 );
+                poFieldDescFeature->SetField( szFIELD_CATEGORY, szSWE_FIELD );
+                if( psChildNode )
+                {
+                    CPLXMLNode* psDupTree = CPLCloneXMLTree(psChildNode);
+                    CPLXMLNode* psValue = CPLGetXMLNode(psDupTree, "value");
+                    if( psValue != NULL )
+                        CPLRemoveXMLChild(psDupTree, psValue);
+                    char* pszXML = CPLSerializeXMLTree(psDupTree);
+                    CPLDestroyXMLNode(psDupTree);
+                    poFieldDescFeature->SetField( szFIELD_DOCUMENTATION, pszXML);
+                    CPLFree(pszXML);
+                }
+                CPL_IGNORE_RET_VAL(
+                    poFieldsMetadataLayer->CreateFeature(poFieldDescFeature));
+                delete poFieldDescFeature;
+
+                for(  CPLXMLNode* psIter2 = psChildNode->psChild;
+                        psIter2 != NULL; psIter2 = psIter2->psNext )
+                {
+                    if( psIter2->eType == CXT_Element &&
+                        strcmp(psIter2->pszValue, "value") != 0 )
+                    {
+                        CPLString osName2(osName + "_" + psIter2->pszValue);
+                        osName2.tolower();
+                        for(  CPLXMLNode* psIter3 = psIter2->psChild;
+                                psIter3 != NULL; psIter3 = psIter3->psNext )
+                        {
+                            if( psIter3->eType == CXT_Attribute )
+                            {
+                                const char* pszValue = psIter3->pszValue;
+                                const char* pszColon = strchr(pszValue, ':');
+                                if( pszColon )
+                                    pszValue = pszColon + 1;
+                                CPLString osName3(osName2 + "_" + pszValue);
+                                osName3.tolower();
+                                OGRFieldDefn oFieldDefn2(osName3, OFTString);
+                                m_poFeatureDefn->AddFieldDefn(&oFieldDefn2);
+                            }
+                            else if( psIter3->eType == CXT_Text )
+                            {
+                                OGRFieldDefn oFieldDefn2(osName2, OFTString);
+                                m_poFeatureDefn->AddFieldDefn(&oFieldDefn2);
+                            }
+                        }
+                    }
+                }
+
+                int *panRemap = static_cast<int *>(
+                    CPLMalloc(sizeof(int) * m_poFeatureDefn->GetFieldCount()) );
+                for( int i = 0; i < m_poFeatureDefn->GetFieldCount(); ++i )
+                {
+                    if( i < nValidFields )
+                        panRemap[i] = i;
+                    else
+                        panRemap[i] = -1;
+                }
+
+                for( size_t i = 0; i < apoFeatures.size(); i++ )
+                {
+                    apoFeatures[i]->RemapFields( NULL, panRemap );
+                }
+
+                CPLFree( panRemap );
+            }
+        }
+    }
+}
+
+/************************************************************************/
+/*                             SetSWEValue()                            */
+/************************************************************************/
+
+static void SetSWEValue(OGRFeature* poFeature, const CPLString& osFieldName,
+                        const char* pszValue)
+{
+    int iField = poFeature->GetDefnRef()->GetFieldIndex(osFieldName);
+    OGRFieldDefn* poFieldDefn = poFeature->GetFieldDefnRef(iField);
+    OGRFieldType eType(poFieldDefn->GetType());
+    OGRFieldSubType eSubType(poFieldDefn->GetSubType());
+    if( eType == OFTInteger && eSubType == OFSTBoolean )
+    {
+        poFeature->SetField(iField, EQUAL(pszValue, "1") ||
+                                    EQUAL(pszValue, "True") ? 1 : 0);
+    }
+    else
+    {
+        poFeature->SetField(iField, pszValue);
+    }
+}
+
+/************************************************************************/
+/*                    ProcessDataRecordFillFeature()                    */
+/************************************************************************/
+
+void OGRGMLASLayer::ProcessDataRecordFillFeature(CPLXMLNode* psDataRecord,
+                                                 OGRFeature* poFeature)
+{
+    for( CPLXMLNode* psIter = psDataRecord->psChild;
+                        psIter != NULL; psIter = psIter->psNext )
+    {
+        if( psIter->eType == CXT_Element &&
+            strcmp(psIter->pszValue, "field") == 0 )
+        {
+            CPLString osName = CPLGetXMLValue(psIter, "name", "");
+            osName = osName.tolower();
+            OGRFieldDefn oFieldDefn(osName, OFTString);
+            OGRFieldType eType;
+            OGRFieldSubType eSubType;
+            CPLXMLNode* psChildNode = GetSWEChildAndType(psIter, eType, eSubType);
+            oFieldDefn.SetType(eType);
+            oFieldDefn.SetSubType(eSubType);
+            if( psChildNode == NULL )
+                continue;
+            std::map<CPLString, CPLString>::const_iterator oIter =
+                m_oMapSWEFieldToOGRFieldName.find(osName);
+            CPLAssert( oIter != m_oMapSWEFieldToOGRFieldName.end() );
+            osName = oIter->second;
+            for(  CPLXMLNode* psIter2 = psChildNode->psChild;
+                        psIter2 != NULL; psIter2 = psIter2->psNext )
+            {
+                if( psIter2->eType == CXT_Element )
+                {
+                    CPLString osName2(osName + "_" + psIter2->pszValue);
+                    osName2.tolower();
+                    for(  CPLXMLNode* psIter3 = psIter2->psChild;
+                            psIter3 != NULL; psIter3 = psIter3->psNext )
+                    {
+                        if( psIter3->eType == CXT_Attribute )
+                        {
+                            const char* pszValue = psIter3->pszValue;
+                            const char* pszColon = strchr(pszValue, ':');
+                            if( pszColon )
+                                pszValue = pszColon + 1;
+                            CPLString osName3(osName2 + "_" + pszValue);
+                            osName3.tolower();
+                            SetSWEValue(poFeature, osName3,
+                                                psIter3->psChild->pszValue );
+                        }
+                        else if( psIter3->eType == CXT_Text )
+                        {
+                            SetSWEValue(poFeature, osName2, psIter3->pszValue );
+                        }
+                    }
+                }
             }
-            m_poFeatureDefn->AddFieldDefn(&oFieldDefn);
         }
     }
 }
@@ -339,6 +618,7 @@ void OGRGMLASLayer::PostInit( bool bIncludeGeometryXML )
         poFieldDescFeature->SetField( szLAYER_NAME, GetName() );
 
         ++nFieldIndex;
+        m_nMaxFieldIndex = nFieldIndex;
         poFieldDescFeature->SetField( szFIELD_INDEX, nFieldIndex);
 
         if( oField.GetName().empty() )
@@ -724,6 +1004,29 @@ OGRGMLASLayer::~OGRGMLASLayer()
 }
 
 /************************************************************************/
+/*                        DeleteTargetIndex()                           */
+/************************************************************************/
+
+static void DeleteTargetIndex(std::map<CPLString, int>& oMap, int nIdx)
+{
+    bool bIterToRemoveValid = false;
+    std::map<CPLString, int>::iterator oIterToRemove;
+    std::map<CPLString, int>::iterator oIter = oMap.begin();
+    for( ; oIter != oMap.end(); ++oIter )
+    {
+        if( oIter->second > nIdx )
+            oIter->second --;
+        else if( oIter->second == nIdx )
+        {
+            bIterToRemoveValid = true;
+            oIterToRemove = oIter;
+        }
+    }
+    if( bIterToRemoveValid )
+        oMap.erase(oIterToRemove);
+}
+
+/************************************************************************/
 /*                            RemoveField()                             */
 /************************************************************************/
 
@@ -735,19 +1038,7 @@ bool OGRGMLASLayer::RemoveField( int nIdx )
     m_poFeatureDefn->DeleteFieldDefn( nIdx );
 
     // Refresh maps
-    {
-        std::map<CPLString, int>       oMapFieldXPathToOGRFieldIdx;
-        std::map<CPLString, int>::const_iterator oIter =
-                            m_oMapFieldXPathToOGRFieldIdx.begin();
-        for( ; oIter != m_oMapFieldXPathToOGRFieldIdx.end(); ++oIter )
-        {
-            if( oIter->second < nIdx )
-                oMapFieldXPathToOGRFieldIdx[oIter->first] = oIter->second;
-            else if( oIter->second > nIdx )
-                oMapFieldXPathToOGRFieldIdx[oIter->first] = oIter->second - 1;
-        }
-        m_oMapFieldXPathToOGRFieldIdx = oMapFieldXPathToOGRFieldIdx;
-    }
+    DeleteTargetIndex(m_oMapFieldXPathToOGRFieldIdx, nIdx);
 
     {
         std::map<int, int>             oMapOGRFieldIdxtoFCFieldIdx;
@@ -767,6 +1058,20 @@ bool OGRGMLASLayer::RemoveField( int nIdx )
 }
 
 /************************************************************************/
+/*                        InsertTargetIndex()                           */
+/************************************************************************/
+
+static void InsertTargetIndex(std::map<CPLString, int>& oMap, int nIdx)
+{
+    std::map<CPLString, int>::iterator oIter = oMap.begin();
+    for( ; oIter != oMap.end(); ++oIter )
+    {
+        if( oIter->second >= nIdx )
+            oIter->second ++;
+    }
+}
+
+/************************************************************************/
 /*                            InsertNewField()                          */
 /************************************************************************/
 
@@ -790,20 +1095,8 @@ void OGRGMLASLayer::InsertNewField( int nInsertPos,
     delete[] panMap;
 
     // Refresh maps
-    {
-        std::map<CPLString, int>       oMapFieldXPathToOGRFieldIdx;
-        std::map<CPLString, int>::const_iterator oIter =
-                            m_oMapFieldXPathToOGRFieldIdx.begin();
-        for( ; oIter != m_oMapFieldXPathToOGRFieldIdx.end(); ++oIter )
-        {
-            if( oIter->second < nInsertPos )
-                oMapFieldXPathToOGRFieldIdx[oIter->first] = oIter->second;
-            else
-                oMapFieldXPathToOGRFieldIdx[oIter->first] = oIter->second + 1;
-        }
-        m_oMapFieldXPathToOGRFieldIdx = oMapFieldXPathToOGRFieldIdx;
-        m_oMapFieldXPathToOGRFieldIdx[ osXPath ] = nInsertPos;
-    }
+    InsertTargetIndex(m_oMapFieldXPathToOGRFieldIdx, nInsertPos);
+    m_oMapFieldXPathToOGRFieldIdx[ osXPath ] = nInsertPos;
 
     {
         std::map<int, int>             oMapOGRFieldIdxtoFCFieldIdx;
diff --git a/ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp b/ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp
index 91b3548..bef859e 100644
--- a/ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp
+++ b/ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp
@@ -35,7 +35,7 @@
 
 #include "ogr_json_header.h"
 
-CPL_CVSID("$Id: ogrgmlasreader.cpp 37972 2017-04-12 16:13:12Z rouault $");
+CPL_CVSID("$Id: ogrgmlasreader.cpp 38073 2017-04-20 17:00:47Z rouault $");
 
 /************************************************************************/
 /*                        GMLASBinInputStream                           */
@@ -396,7 +396,12 @@ GMLASReader::GMLASReader(GMLASXSDCache& oCache,
     m_eSwapCoordinates = GMLAS_SWAP_AUTO;
     m_bInitialPass = false;
     m_bProcessSWEDataArray = false;
+    m_bProcessSWEDataRecord = false;
     m_nSWEDataArrayLevel = -1;
+    m_nSWEDataRecordLevel = -1;
+    m_poFieldsMetadataLayer = NULL;
+    m_poLayersMetadataLayer = NULL;
+    m_poRelationshipsLayer = NULL;
     m_nFileSize = 0;
     m_bWarnUnexpected =
         CPLTestBool(CPLGetConfigOption("GMLAS_WARN_UNEXPECTED", "FALSE"));
@@ -871,7 +876,8 @@ void GMLASReader::BuildXMLBlobStartElement(const CPLString& osXPath,
     }
 
     CPLXMLNode* psNode = NULL;
-    if( m_nCurGeomFieldIdx >= 0 || m_nSWEDataArrayLevel >= 0 )
+    if( m_nCurGeomFieldIdx >= 0 || m_nSWEDataArrayLevel >= 0 ||
+        m_nSWEDataRecordLevel >= 0 )
     {
         psNode = CPLCreateXMLNode( NULL, CXT_Element, osXPath );
         if( !m_apsXMLNodeStack.empty() )
@@ -1105,17 +1111,28 @@ void GMLASReader::startElement(
     }
 
     if( m_bProcessSWEDataArray && m_nSWEDataArrayLevel < 0 &&
-        m_nCurGeomFieldIdx < 0 )
+        m_nSWEDataRecordLevel < 0 && m_nCurGeomFieldIdx < 0 )
     {
         if( osNSURI == szSWE_URI &&
-            osLocalname == "DataArray" )
+            (osLocalname == "DataArray" || osLocalname == "DataStream") )
         {
+            if( m_nCurFieldIdx >= 0 )
+            {
+                m_osSWEDataArrayParentField =
+                    m_oCurCtxt.m_poFeature->
+                                GetFieldDefnRef(m_nCurFieldIdx)->GetNameRef();
+            }
+            else
+            {
+                m_osSWEDataArrayParentField.clear();
+            }
             m_nSWEDataArrayLevel = m_nLevel;
         }
     }
 
     // Deal with XML content
-    if( m_bIsXMLBlob || m_nSWEDataArrayLevel >= 0 )
+    if( m_bIsXMLBlob || m_nSWEDataArrayLevel >= 0 ||
+        m_nSWEDataRecordLevel >= 0 )
     {
         BuildXMLBlobStartElement(osXPath, attrs);
     }
@@ -1521,11 +1538,10 @@ void GMLASReader::startElement(
                 const GMLASField& oField(
                     m_oCurCtxt.m_poLayer->GetFeatureClass().GetFields()[
                                                                 nFCFieldIdx]);
-                m_bIsXMLBlob = (oField.GetType() == GMLAS_FT_ANYTYPE ||
-                                m_nCurGeomFieldIdx != -1 );
-                if( m_bIsXMLBlob )
+                if( m_nSWEDataArrayLevel < 0 && m_nSWEDataRecordLevel < 0 )
                 {
-                    CPLAssert( m_nSWEDataArrayLevel < 0 );
+                    m_bIsXMLBlob = (oField.GetType() == GMLAS_FT_ANYTYPE ||
+                                    m_nCurGeomFieldIdx != -1 );
                 }
                 m_bIsXMLBlobIncludeUpper = m_bIsXMLBlob &&
                                             oField.GetIncludeThisEltInBlob();
@@ -1583,6 +1599,15 @@ void GMLASReader::startElement(
                                   poOldLayer,
                                   nOldCurFieldIdx,
                                   osChildId );
+
+                        if( m_bProcessSWEDataRecord && !m_bIsXMLBlob &&
+                            m_nSWEDataArrayLevel < 0 &&
+                            m_nSWEDataRecordLevel < 0 &&
+                            osNestedXPath == "swe:DataRecord" )
+                        {
+                            m_nSWEDataRecordLevel = m_nLevel;
+                            BuildXMLBlobStartElement(osXPath, attrs);
+                        }
                     }
                 }
             }
@@ -2440,6 +2465,59 @@ void GMLASReader::endElement(
         m_osCurSubXPath.resize( m_osCurSubXPath.size() - 1 - nLastXPathLength);
     else if( m_osCurSubXPath.size() == nLastXPathLength )
          m_osCurSubXPath.clear();
+
+    if( m_nSWEDataRecordLevel >= 0)
+    {
+        if( m_nLevel > m_nSWEDataRecordLevel )
+        {
+            CPLAssert( m_apsXMLNodeStack.size() > 1 );
+            m_apsXMLNodeStack.pop_back();
+        }
+        else
+        {
+            CPLAssert( m_apsXMLNodeStack.size() == 1 );
+            CPLXMLNode* psRoot = m_apsXMLNodeStack[0].psNode;
+            ProcessSWEDataRecord(psRoot);
+            m_nSWEDataRecordLevel = -1;
+            CPLDestroyXMLNode(psRoot);
+            m_apsXMLNodeStack.clear();
+        }
+    }
+}
+
+/************************************************************************/
+/*                             SetSWEValue()                            */
+/************************************************************************/
+
+static void SetSWEValue(OGRFeature* poFeature, int iField, CPLString& osValue)
+{
+    if( !osValue.empty() )
+    {
+        OGRFieldDefn* poFieldDefn = poFeature->GetFieldDefnRef(iField);
+        OGRFieldType eType(poFieldDefn->GetType());
+        OGRFieldSubType eSubType(poFieldDefn->GetSubType());
+        if( eType == OFTReal || eType == OFTInteger)
+        {
+            osValue.Trim();
+            if( eSubType == OFSTBoolean )
+            {
+                osValue = EQUAL(osValue, "1") ||
+                          EQUAL(osValue, "True") ? "1" : "0";
+            }
+        }
+        poFeature->SetField(iField, osValue.c_str());
+    }
+}
+
+/************************************************************************/
+/*                              SkipSpace()                             */
+/************************************************************************/
+
+static size_t SkipSpace( const char* pszValues, size_t i )
+{
+    while( isspace( static_cast<int>(pszValues[i]) ) )
+        i ++;
+    return i;
 }
 
 /************************************************************************/
@@ -2484,8 +2562,49 @@ void GMLASReader::ProcessSWEDataArray(CPLXMLNode* psRoot)
         }
         osLayerName = osLayerName.tolower();
         OGRGMLASLayer* poLayer = new OGRGMLASLayer(osLayerName);
+
+        // Register layer in _ogr_layers_metadata
+        {
+            OGRFeature* poLayerDescFeature =
+                        new OGRFeature(m_poLayersMetadataLayer->GetLayerDefn());
+            poLayerDescFeature->SetField( szLAYER_NAME, osLayerName );
+            poLayerDescFeature->SetField( szLAYER_CATEGORY, szSWE_DATA_ARRAY );
+
+            CPLString osFieldName(szPARENT_PREFIX);
+            osFieldName += m_oCurCtxt.m_poLayer->GetLayerDefn()->GetFieldDefn(
+                        m_oCurCtxt.m_poLayer->GetIDFieldIdx())->GetNameRef();
+            poLayerDescFeature->SetField( szLAYER_PARENT_PKID_NAME,
+                                          osFieldName.c_str() );
+            CPL_IGNORE_RET_VAL(
+                m_poLayersMetadataLayer->CreateFeature(poLayerDescFeature));
+            delete poLayerDescFeature;
+        }
+
+        // Register layer relationship in _ogr_layer_relationships
+        {
+            OGRFeature* poRelationshipsFeature =
+                new OGRFeature(m_poRelationshipsLayer->GetLayerDefn());
+            poRelationshipsFeature->SetField( szPARENT_LAYER,
+                                              m_oCurCtxt.m_poLayer->GetName() );
+            poRelationshipsFeature->SetField( szPARENT_PKID,
+                    m_oCurCtxt.m_poLayer->GetLayerDefn()->GetFieldDefn(
+                        m_oCurCtxt.m_poLayer->GetIDFieldIdx())->GetNameRef() );
+            if( !m_osSWEDataArrayParentField.empty() )
+            {
+                poRelationshipsFeature->SetField( szPARENT_ELEMENT_NAME,
+                                                  m_osSWEDataArrayParentField );
+            }
+            poRelationshipsFeature->SetField(szCHILD_LAYER,
+                                             osLayerName);
+            CPL_IGNORE_RET_VAL(m_poRelationshipsLayer->CreateFeature(
+                                            poRelationshipsFeature));
+            delete poRelationshipsFeature;
+        }
+
         m_apoSWEDataArrayLayers.push_back(poLayer);
-        poLayer->ProcessDataRecord(psDataRecord);
+        poLayer->ProcessDataRecordOfDataArrayCreateFields(m_oCurCtxt.m_poLayer,
+                                                          psDataRecord,
+                                                          m_poFieldsMetadataLayer);
     }
     else
     {
@@ -2493,15 +2612,14 @@ void GMLASReader::ProcessSWEDataArray(CPLXMLNode* psRoot)
                     static_cast<int>(m_apoSWEDataArrayLayers.size()) );
         OGRGMLASLayer* poLayer =
                         m_apoSWEDataArrayLayers[m_nSWEDataArrayLayerIdx];
-        const int nFieldCount = poLayer->GetLayerDefn()->GetFieldCount();
+        // -1 because first field is parent id
+        const int nFieldCount = poLayer->GetLayerDefn()->GetFieldCount() - 1;
         int nFID = 1;
         int iField = 0;
         const size_t nLen = strlen(pszValues);
         OGRFeature* poFeature = NULL;
         const bool bSameSep = (osTokenSeparator == osBlockSeparator);
-        size_t nLastValid = 0;
-        while( isspace( static_cast<int>(pszValues[nLastValid]) ) )
-            nLastValid ++;
+        size_t nLastValid = SkipSpace(pszValues, 0);
         size_t i = nLastValid;
         while( i < nLen )
         {
@@ -2509,6 +2627,9 @@ void GMLASReader::ProcessSWEDataArray(CPLXMLNode* psRoot)
             {
                 poFeature = new OGRFeature( poLayer->GetLayerDefn() );
                 poFeature->SetFID( nFID );
+                poFeature->SetField( 0,
+                    m_oCurCtxt.m_poFeature->GetFieldAsString(
+                        m_oCurCtxt.m_poLayer->GetIDFieldIdx()));
                 nFID ++;
                 iField = 0;
             }
@@ -2520,21 +2641,23 @@ void GMLASReader::ProcessSWEDataArray(CPLXMLNode* psRoot)
                     PushFeatureReady( poFeature, poLayer );
                     poFeature = new OGRFeature( poLayer->GetLayerDefn() );
                     poFeature->SetFID( nFID );
+                    poFeature->SetField( 0,
+                        m_oCurCtxt.m_poFeature->GetFieldAsString(
+                            m_oCurCtxt.m_poLayer->GetIDFieldIdx()));
                     nFID ++;
                     iField = 0;
                 }
 
                 if( iField < nFieldCount )
                 {
-                    std::string osValue( pszValues + nLastValid,
-                                         i - nLastValid );
-                    if( !osValue.empty() )
-                        poFeature->SetField(iField, osValue.c_str());
+                    CPLString osValue( pszValues + nLastValid,
+                                       i - nLastValid );
+                    // +1 because first field is parent id
+                    SetSWEValue(poFeature, iField+1, osValue);
                     iField ++;
                 }
                 nLastValid = i + osTokenSeparator.size();
-                while( isspace( static_cast<int>(pszValues[nLastValid]) ) )
-                    nLastValid ++;
+                nLastValid = SkipSpace(pszValues, nLastValid);
                 i = nLastValid;
             }
             else if( strncmp( pszValues + i, osBlockSeparator,
@@ -2542,17 +2665,16 @@ void GMLASReader::ProcessSWEDataArray(CPLXMLNode* psRoot)
             {
                 if( iField < nFieldCount )
                 {
-                    std::string osValue( pszValues + nLastValid,
-                                         i - nLastValid );
-                    if( !osValue.empty() )
-                        poFeature->SetField(iField, osValue.c_str());
+                    CPLString osValue( pszValues + nLastValid,
+                                       i - nLastValid );
+                    // +1 because first field is parent id
+                    SetSWEValue(poFeature, iField+1, osValue);
                     iField ++;
                 }
                 PushFeatureReady( poFeature, poLayer );
                 poFeature = NULL;
                 nLastValid = i + osBlockSeparator.size();
-                while( isspace( static_cast<int>(pszValues[nLastValid]) ) )
-                    nLastValid ++;
+                nLastValid = SkipSpace(pszValues, nLastValid);
                 i = nLastValid;
             }
             else
@@ -2564,10 +2686,10 @@ void GMLASReader::ProcessSWEDataArray(CPLXMLNode* psRoot)
         {
             if( iField < nFieldCount )
             {
-                std::string osValue( pszValues + nLastValid,
-                                     nLen - nLastValid );
-                if( !osValue.empty() )
-                    poFeature->SetField(iField, osValue.c_str());
+                CPLString osValue( pszValues + nLastValid,
+                                    nLen - nLastValid );
+                // +1 because first field is parent id
+                SetSWEValue(poFeature, iField+1, osValue);
                 //iField ++;
             }
             PushFeatureReady( poFeature, poLayer );
@@ -2576,6 +2698,35 @@ void GMLASReader::ProcessSWEDataArray(CPLXMLNode* psRoot)
     m_nSWEDataArrayLayerIdx ++;
 }
 
+
+/************************************************************************/
+/*                        ProcessSWEDataRecord()                        */
+/************************************************************************/
+
+void GMLASReader::ProcessSWEDataRecord(CPLXMLNode* psRoot)
+{
+    CPLStripXMLNamespace( psRoot, "swe", true );
+    if( m_bInitialPass )
+    {
+        // Collect existing live features of this layer, so that we can
+        // patch them
+        std::vector<OGRFeature*> apoFeatures;
+        apoFeatures.push_back(m_oCurCtxt.m_poFeature);
+        for(size_t i = 0; i < m_aoFeaturesReady.size(); ++i )
+        {
+            if( m_aoFeaturesReady[i].second == m_oCurCtxt.m_poLayer )
+                apoFeatures.push_back(m_aoFeaturesReady[i].first);
+        }
+        m_oCurCtxt.m_poLayer->ProcessDataRecordCreateFields(
+            psRoot, apoFeatures, m_poFieldsMetadataLayer);
+    }
+    else
+    {
+        m_oCurCtxt.m_poLayer->ProcessDataRecordFillFeature(
+            psRoot, m_oCurCtxt.m_poFeature);
+    }
+}
+
 /************************************************************************/
 /*                            ProcessGeometry()                         */
 /************************************************************************/
@@ -2748,8 +2899,8 @@ void GMLASReader::characters( const XMLCh *const chars,
                               const XMLSize_t length )
 {
     bool bTextMemberUpdated = false;
-    if( ((m_bIsXMLBlob && m_nCurGeomFieldIdx >= 0 && FillTextContent()) ||
-        m_nSWEDataArrayLevel >= 0) &&
+    if( ((m_bIsXMLBlob && m_nCurGeomFieldIdx >= 0 && !m_bInitialPass) ||
+        m_nSWEDataArrayLevel >= 0 || m_nSWEDataRecordLevel >= 0) &&
         // Check the stack is not empty in case of space chars before the
         // starting node
         !m_apsXMLNodeStack.empty() )
@@ -2967,10 +3118,16 @@ bool GMLASReader::RunFirstPass(GDALProgressFunc pfnProgress,
                                bool bRemoveUnusedLayers,
                                bool bRemoveUnusedFields,
                                bool bProcessSWEDataArray,
+                               OGRLayer* poFieldsMetadataLayer,
+                               OGRLayer* poLayersMetadataLayer,
+                               OGRLayer* poRelationshipsLayer,
                                std::set<CPLString>& aoSetRemovedLayerNames)
 {
     m_bInitialPass = true;
     m_bProcessSWEDataArray = bProcessSWEDataArray;
+    m_poFieldsMetadataLayer = poFieldsMetadataLayer;
+    m_poLayersMetadataLayer = poLayersMetadataLayer;
+    m_poRelationshipsLayer = poRelationshipsLayer;
 
     // Store in m_oSetGeomFieldsWithUnknownSRS the geometry fields
     std::set<OGRGMLASLayer*> oSetUnreferencedLayers;
diff --git a/ogr/ogrsf_frmts/gmlas/ogrgmlasschemaanalyzer.cpp b/ogr/ogrsf_frmts/gmlas/ogrgmlasschemaanalyzer.cpp
index f177c95..8dba4f0 100644
--- a/ogr/ogrsf_frmts/gmlas/ogrgmlasschemaanalyzer.cpp
+++ b/ogr/ogrsf_frmts/gmlas/ogrgmlasschemaanalyzer.cpp
@@ -41,7 +41,7 @@ static XSModel* getGrammarPool(XMLGrammarPool* pool)
 #include "ogr_gmlas.h"
 #include "ogr_pgdump.h"
 
-CPL_CVSID("$Id: ogrgmlasschemaanalyzer.cpp 37871 2017-03-31 16:39:20Z rouault $");
+CPL_CVSID("$Id: ogrgmlasschemaanalyzer.cpp 38073 2017-04-20 17:00:47Z rouault $");
 
 /************************************************************************/
 /*                        IsCompatibleOfArray()                         */
@@ -1494,6 +1494,12 @@ static bool IsAnyType(XSComplexTypeDefinition* poType)
                 }
             }
         }
+        else if( poType->getDerivationMethod() ==
+                                            XSConstants::DERIVATION_EXTENSION )
+        {
+            // swe:values case
+            return true;
+        }
     }
     return false;
 }
@@ -2198,16 +2204,21 @@ bool GMLASSchemaAnalyzer::FindElementsWithMustBeToLevel(
                             aoSetXPathEltsForTopClass.find( osXPath )
                                 == aoSetXPathEltsForTopClass.end() )
                         {
+                            CPLString osIgnored;
+                            if( !m_oForcedFlattenedXPathMatcher.MatchesRefXPath(
+                                                        osXPath, osIgnored))
+                            {
 #ifdef DEBUG_VERBOSE
-                            CPLDebug("GMLAS", "%s (%s) must be exposed as "
-                                     "top-level (multiple time referenced)",
-                                     osXPath.c_str(),
-                                     transcode(
-                                        poTypeDef->getNamespace()).c_str());
+                                CPLDebug("GMLAS", "%s (%s) must be exposed as "
+                                        "top-level (multiple time referenced)",
+                                        osXPath.c_str(),
+                                        transcode(
+                                            poTypeDef->getNamespace()).c_str());
 #endif
-                            m_oSetEltsForTopClass.insert(poElt);
-                            oVectorEltsForTopClass.push_back(poElt);
-                            aoSetXPathEltsForTopClass.insert( osXPath );
+                                m_oSetEltsForTopClass.insert(poElt);
+                                oVectorEltsForTopClass.push_back(poElt);
+                                aoSetXPathEltsForTopClass.insert( osXPath );
+                            }
                         }
                     }
                     else
diff --git a/ogr/ogrsf_frmts/gmlas/ogrgmlaswriter.cpp b/ogr/ogrsf_frmts/gmlas/ogrgmlaswriter.cpp
index a55d45a..5eaf4b3 100644
--- a/ogr/ogrsf_frmts/gmlas/ogrgmlaswriter.cpp
+++ b/ogr/ogrsf_frmts/gmlas/ogrgmlaswriter.cpp
@@ -36,7 +36,7 @@
 
 #include <algorithm>
 
-CPL_CVSID("$Id: ogrgmlaswriter.cpp 37470 2017-02-26 02:23:50Z goatbar $");
+CPL_CVSID("$Id: ogrgmlaswriter.cpp 38073 2017-04-20 17:00:47Z rouault $");
 
 namespace GMLAS
 {
@@ -1061,7 +1061,8 @@ bool GMLASWriter::CollectFields()
         }
     }
 
-    m_poFieldsMDLayer->SetAttributeFilter( NULL );
+    m_poFieldsMDLayer->SetAttributeFilter(
+        (CPLString(szFIELD_CATEGORY) + " != '" + szSWE_FIELD + "'").c_str() );
     m_poFieldsMDLayer->ResetReading();
     while( true )
     {
diff --git a/ogr/ogrsf_frmts/gpkg/ogrgeopackagedatasource.cpp b/ogr/ogrsf_frmts/gpkg/ogrgeopackagedatasource.cpp
index ea2f7ca..cdcd389 100644
--- a/ogr/ogrsf_frmts/gpkg/ogrgeopackagedatasource.cpp
+++ b/ogr/ogrsf_frmts/gpkg/ogrgeopackagedatasource.cpp
@@ -38,7 +38,7 @@
 
 #include <algorithm>
 
-CPL_CVSID("$Id: ogrgeopackagedatasource.cpp 37945 2017-04-10 14:25:25Z rouault $");
+CPL_CVSID("$Id: ogrgeopackagedatasource.cpp 37995 2017-04-14 09:50:49Z rouault $");
 
 /************************************************************************/
 /*                             Tiling schemes                           */
@@ -3003,6 +3003,39 @@ int GDALGeoPackageDataset::Create( const char * pszFilename,
     /* will be written into the main file and supported henceforth */
     SQLCommand(hDB, "PRAGMA encoding = \"UTF-8\"");
 
+    if( bFileExists )
+    {
+        VSILFILE* fp = VSIFOpenL(pszFilename, "rb");
+        if( fp )
+        {
+            GByte abyHeader[100];
+            VSIFReadL(abyHeader, 1, sizeof(abyHeader), fp);
+            VSIFCloseL(fp);
+
+            memcpy(&m_nApplicationId, abyHeader + knApplicationIdPos, 4);
+            m_nApplicationId = CPL_MSBWORD32(m_nApplicationId);
+            memcpy(&m_nUserVersion, abyHeader + knUserVersionPos, 4);
+            m_nUserVersion = CPL_MSBWORD32(m_nUserVersion);
+
+            if( m_nApplicationId == GP10_APPLICATION_ID )
+            {
+                CPLDebug("GPKG", "GeoPackage v1.0");
+            }
+            else if( m_nApplicationId == GP11_APPLICATION_ID )
+            {
+                CPLDebug("GPKG", "GeoPackage v1.1");
+            }
+            else if( m_nApplicationId == GPKG_APPLICATION_ID &&
+                    m_nUserVersion >= GPKG_1_2_VERSION )
+            {
+                CPLDebug("GPKG", "GeoPackage v%d.%d.%d",
+                        m_nUserVersion / 10000,
+                        (m_nUserVersion % 10000) / 100,
+                        m_nUserVersion % 100);
+            }
+        }
+    }
+
     if( nBandsIn > 0 && eDT != GDT_Byte )
     {
         m_nApplicationId = GPKG_APPLICATION_ID;
@@ -4898,7 +4931,8 @@ void GDALGeoPackageDataset::CheckUnknownExtensions(bool bCheckRasterTable)
             "AND scope IS NOT NULL "
             "AND extension_name != 'gdal_aspatial' "
             "AND extension_name != 'gpkg_elevation_tiles' "
-            "AND extension_name != 'gpkg_metadata') "
+            "AND extension_name != 'gpkg_metadata' "
+            "AND extension_name != 'gpkg_schema') "
 #ifdef WORKAROUND_SQLITE3_BUGS
             "OR 0 "
 #endif
@@ -4912,7 +4946,8 @@ void GDALGeoPackageDataset::CheckUnknownExtensions(bool bCheckRasterTable)
             "AND definition IS NOT NULL "
             "AND scope IS NOT NULL "
             "AND extension_name != 'gpkg_elevation_tiles' "
-            "AND extension_name != 'gpkg_metadata') "
+            "AND extension_name != 'gpkg_metadata' "
+            "AND extension_name != 'gpkg_schema') "
 #ifdef WORKAROUND_SQLITE3_BUGS
             "OR 0 "
 #endif
diff --git a/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp b/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp
index c27af54..054efe2 100644
--- a/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp
+++ b/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp
@@ -33,7 +33,7 @@
 #include "cpl_time.h"
 #include "ogr_p.h"
 
-CPL_CVSID("$Id: ogrgeopackagetablelayer.cpp 37814 2017-03-20 20:37:16Z rouault $");
+CPL_CVSID("$Id: ogrgeopackagetablelayer.cpp 38036 2017-04-16 12:35:59Z rouault $");
 
 static const char UNSUPPORTED_OP_READ_ONLY[] =
   "%s : unsupported operation on a read-only datasource.";
@@ -1647,7 +1647,7 @@ OGRErr OGRGeoPackageTableLayer::ISetFeature( OGRFeature *poFeature )
             /* Construct a SQL INSERT statement from the OGRFeature */
             /* Only work with fields that are set */
             /* Do not stick values into SQL, use placeholder and bind values later */
-            CPLString osCommand = FeatureGenerateInsertSQL(poFeature, true);
+            CPLString osCommand = FeatureGenerateInsertSQL(poFeature, true, true);
 
             /* Prepare the SQL into a statement */
             int err = sqlite3_prepare_v2(m_poDS->GetDB(), osCommand, -1, &m_poUpdateStatement, NULL);
@@ -1670,7 +1670,7 @@ OGRErr OGRGeoPackageTableLayer::ISetFeature( OGRFeature *poFeature )
             return errOgr;
 
         /* Bind values onto the statement now */
-        errOgr = FeatureBindInsertParameters(poFeature, m_poUpdateStatement, true);
+        errOgr = FeatureBindInsertParameters(poFeature, m_poUpdateStatement, true, true);
         if ( errOgr != OGRERR_NONE )
             return errOgr;
     }
diff --git a/ogr/ogrsf_frmts/oci/ogr_oci.h b/ogr/ogrsf_frmts/oci/ogr_oci.h
index 2438475..62aa84b 100644
--- a/ogr/ogrsf_frmts/oci/ogr_oci.h
+++ b/ogr/ogrsf_frmts/oci/ogr_oci.h
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: ogr_oci.h 36501 2016-11-25 14:09:24Z rouault $
+ * $Id: ogr_oci.h 38061 2017-04-19 05:23:56Z ilucena $
  *
  * Project:  Oracle Spatial Driver
  * Purpose:  Oracle Spatial OGR Driver Declarations.
@@ -121,11 +121,15 @@ class CPL_DLL OGROCISession {
     CPLErr   GetParmInfo( OCIParam *hParmDesc, OGRFieldDefn *poOGRDefn,
                           ub2 *pnOCIType, ub4 *pnOCILen );
 
-    static void     CleanName( char * );
+    void     CleanName( char * );
 
     OCIType *PinTDO( const char * );
 
   private:
+
+    int         nServerVersion;
+    int         nServerRelease;
+    size_t      nMaxNameLength;
 };
 
 OGROCISession CPL_DLL*
@@ -524,11 +528,11 @@ class OGROCIDataSource : public OGRDataSource
 
     OGROCISession      *GetSession() { return poSession; }
 
-    int                 Open( const char *, char** papszOpenOptions,
+    int                 Open( const char *, char** papszOpenOptionsIn,
                               int bUpdate, int bTestOpen );
     int                 OpenTable( const char *pszTableName,
                                    int nSRID, int bUpdate, int bTestOpen,
-                                   char** papszOpenOptions );
+                                   char** papszOpenOptionsIn );
 
     const char          *GetName() override { return pszName; }
     int                 GetLayerCount() override { return nLayers; }
diff --git a/ogr/ogrsf_frmts/oci/ogrocidatasource.cpp b/ogr/ogrsf_frmts/oci/ogrocidatasource.cpp
index db46b32..00622e9 100644
--- a/ogr/ogrsf_frmts/oci/ogrocidatasource.cpp
+++ b/ogr/ogrsf_frmts/oci/ogrocidatasource.cpp
@@ -30,7 +30,7 @@
 #include "cpl_conv.h"
 #include "cpl_string.h"
 
-CPL_CVSID("$Id: ogrocidatasource.cpp 36385 2016-11-21 12:24:06Z rouault $");
+CPL_CVSID("$Id: ogrocidatasource.cpp 38061 2017-04-19 05:23:56Z ilucena $");
 
 static const int anEPSGOracleMapping[] =
 {
@@ -139,7 +139,7 @@ int OGROCIDataSource::Open( const char * pszNewName,
         const char* pszTables = CSLFetchNameValue(papszOpenOptionsIn, "TABLES");
         if( pszTables )
             papszTableList = CSLTokenizeStringComplex(pszTables, ",", TRUE, FALSE );
-        pszWorkspace = CSLFetchNameValueDef(papszOpenOptions, "WORKSPACE", "");
+        pszWorkspace = CSLFetchNameValueDef(papszOpenOptionsIn, "WORKSPACE", "");
     }
     else
     {
@@ -181,8 +181,6 @@ int OGROCIDataSource::Open( const char * pszNewName,
 /* -------------------------------------------------------------------- */
 /*      Try to establish connection.                                    */
 /* -------------------------------------------------------------------- */
-    CPLDebug( "OCI", "Userid=%s, Password=%s, Database=%s",
-              pszUserid, pszPassword, pszDatabase );
 
     if( EQUAL(pszDatabase, "") &&
         EQUAL(pszPassword, "") &&
diff --git a/ogr/ogrsf_frmts/oci/ogrocisession.cpp b/ogr/ogrsf_frmts/oci/ogrocisession.cpp
index 2a0a587..57ec205 100644
--- a/ogr/ogrsf_frmts/oci/ogrocisession.cpp
+++ b/ogr/ogrsf_frmts/oci/ogrocisession.cpp
@@ -30,7 +30,7 @@
 #include "ogr_oci.h"
 #include "cpl_conv.h"
 
-CPL_CVSID("$Id: ogrocisession.cpp 36802 2016-12-11 23:03:54Z rouault $");
+CPL_CVSID("$Id: ogrocisession.cpp 38061 2017-04-19 05:23:56Z ilucena $");
 
 /************************************************************************/
 /*                          OGRGetOCISession()                          */
@@ -72,6 +72,9 @@ OGROCISession::OGROCISession()
     pszUserid = NULL;
     pszPassword = NULL;
     pszDatabase = NULL;
+    nServerVersion = 10;
+    nServerRelease = 1;
+    nMaxNameLength = 30;
 }
 
 /************************************************************************/
@@ -279,6 +282,51 @@ int OGROCISession::EstablishSession( const char *pszUseridIn,
     pszDatabase = CPLStrdup(pszDatabaseIn);
 
 /* -------------------------------------------------------------------- */
+/*      Get server version information                                  */
+/* -------------------------------------------------------------------- */
+
+    char szVersionTxt[256];
+
+    OCIServerVersion( hSvcCtx, hError, (text*) szVersionTxt, 
+                    (ub4) sizeof(szVersionTxt), (ub1) OCI_HTYPE_SVCCTX );
+
+    char** papszNameValue = CSLTokenizeString2( szVersionTxt, " .", 
+                                                CSLT_STRIPLEADSPACES );
+
+    int count = CSLCount( papszNameValue);
+
+    for( int i = 0; i < count; i++)
+    {
+        if( EQUAL(papszNameValue[i], "Release") )
+        {
+            if( i + 1 < count )
+            {
+                nServerVersion = atoi(papszNameValue[i + 1]);
+            }
+            if( i + 2 < count )
+            {
+                nServerRelease = atoi(papszNameValue[i + 2]);
+            }
+            break;
+        }
+    }
+
+    CPLDebug("OCI", "From '%s' :", szVersionTxt);
+    CPLDebug("OCI", "Version:%d", nServerVersion);
+    CPLDebug("OCI", "Release:%d", nServerRelease);
+
+/* -------------------------------------------------------------------- */
+/*      Set maximun name length (before 12.2 ? 30 : 128)                */
+/* -------------------------------------------------------------------- */
+
+    if( nServerVersion >= 12 && nServerRelease >= 2 )
+    {
+        nMaxNameLength = 128;
+    }
+
+    CPLFree( papszNameValue );
+
+/* -------------------------------------------------------------------- */
 /*      Setting up the OGR compatible time formatting rules.            */
 /* -------------------------------------------------------------------- */
     OGROCIStatement oSetNLSTimeFormat( this );
@@ -510,8 +558,8 @@ void OGROCISession::CleanName( char * pszName )
 {
     int   i;
 
-    if( strlen(pszName) > 30 )
-        pszName[30] = '\0';
+    if( strlen(pszName) > nMaxNameLength )
+        pszName[nMaxNameLength] = '\0';
 
     for( i = 0; pszName[i] != '\0'; i++ )
     {
diff --git a/ogr/ogrsf_frmts/oci/ogrociwritablelayer.cpp b/ogr/ogrsf_frmts/oci/ogrociwritablelayer.cpp
index 467a9b0..ab2eb0a 100644
--- a/ogr/ogrsf_frmts/oci/ogrociwritablelayer.cpp
+++ b/ogr/ogrsf_frmts/oci/ogrociwritablelayer.cpp
@@ -32,7 +32,7 @@
 #include "cpl_conv.h"
 #include "cpl_string.h"
 
-CPL_CVSID("$Id: ogrociwritablelayer.cpp 36347 2016-11-20 20:43:39Z rouault $");
+CPL_CVSID("$Id: ogrociwritablelayer.cpp 38061 2017-04-19 05:23:56Z ilucena $");
 
 /************************************************************************/
 /*                        OGROCIWritableLayer()                         */
@@ -246,7 +246,7 @@ OGRErr OGROCIWritableLayer::CreateField( OGRFieldDefn *poFieldIn, int bApproxOK
 {
     OGROCISession      *poSession = poDS->GetSession();
     char                szFieldType[256];
-    char                szFieldName[30];     // specify at most 30 characters, see ORA-00972
+    char                szFieldName[128]; // 12.2 max identifier name
     OGRFieldDefn        oField( poFieldIn );
 
 /* -------------------------------------------------------------------- */
diff --git a/ogr/ogrsf_frmts/osm/ogrosmdatasource.cpp b/ogr/ogrsf_frmts/osm/ogrosmdatasource.cpp
index f58ce36..51670c2 100644
--- a/ogr/ogrsf_frmts/osm/ogrosmdatasource.cpp
+++ b/ogr/ogrsf_frmts/osm/ogrosmdatasource.cpp
@@ -99,7 +99,7 @@ static const int BUCKET_SECTOR_SIZE_ARRAY_SIZE = 1024;
 
 // Must be a multiple of both BUCKET_BITMAP_SIZE and
 // BUCKET_SECTOR_SIZE_ARRAY_SIZE
-static const int PAGE_SIZE = 4096;
+static const int knPAGE_SIZE = 4096;
 
 // compressSize should not be greater than 512, so COMPRESS_SIZE_TO_BYTE() fits
 // on a byte.
@@ -150,7 +150,7 @@ size_t GetMaxTotalAllocs();
 static void WriteVarInt64(GUIntBig nSVal, GByte** ppabyData);
 static void WriteVarSInt64(GIntBig nSVal, GByte** ppabyData);
 
-CPL_CVSID("$Id: ogrosmdatasource.cpp 37689 2017-03-11 20:30:47Z rouault $");
+CPL_CVSID("$Id: ogrosmdatasource.cpp 38034 2017-04-16 09:42:58Z rouault $");
 
 class DSToBeOpened
 {
@@ -378,13 +378,13 @@ OGROSMDataSource::~OGROSMDataSource()
         {
             if( bCompressNodes )
             {
-                int nRem = i % (PAGE_SIZE / BUCKET_SECTOR_SIZE_ARRAY_SIZE);
+                int nRem = i % (knPAGE_SIZE / BUCKET_SECTOR_SIZE_ARRAY_SIZE);
                 if( nRem == 0 )
                     CPLFree(papsBuckets[i].u.panSectorSize);
             }
             else
             {
-                int nRem = i % (PAGE_SIZE / BUCKET_BITMAP_SIZE);
+                int nRem = i % (knPAGE_SIZE / BUCKET_BITMAP_SIZE);
                 if( nRem == 0 )
                     CPLFree(papsBuckets[i].u.pabyBitmap);
             }
@@ -533,10 +533,10 @@ bool OGROSMDataSource::AllocBucket( int iBucket )
 {
     if( bCompressNodes )
     {
-        const int nRem = iBucket % (PAGE_SIZE / BUCKET_SECTOR_SIZE_ARRAY_SIZE);
+        const int nRem = iBucket % (knPAGE_SIZE / BUCKET_SECTOR_SIZE_ARRAY_SIZE);
         if( papsBuckets[iBucket - nRem].u.panSectorSize == NULL )
             papsBuckets[iBucket - nRem].u.panSectorSize =
-                static_cast<GByte*>(VSI_CALLOC_VERBOSE(1, PAGE_SIZE));
+                static_cast<GByte*>(VSI_CALLOC_VERBOSE(1, knPAGE_SIZE));
         if( papsBuckets[iBucket - nRem].u.panSectorSize != NULL )
         {
             papsBuckets[iBucket].u.panSectorSize =
@@ -548,10 +548,10 @@ bool OGROSMDataSource::AllocBucket( int iBucket )
     }
     else
     {
-        const int nRem = iBucket % (PAGE_SIZE / BUCKET_BITMAP_SIZE);
+        const int nRem = iBucket % (knPAGE_SIZE / BUCKET_BITMAP_SIZE);
         if( papsBuckets[iBucket - nRem].u.pabyBitmap == NULL )
             papsBuckets[iBucket - nRem].u.pabyBitmap =
-                reinterpret_cast<GByte *>(VSI_CALLOC_VERBOSE(1, PAGE_SIZE));
+                reinterpret_cast<GByte *>(VSI_CALLOC_VERBOSE(1, knPAGE_SIZE));
         if( papsBuckets[iBucket - nRem].u.pabyBitmap != NULL )
         {
             papsBuckets[iBucket].u.pabyBitmap =
diff --git a/ogr/ogrsf_frmts/plscenes/ogrplscenesdataset.cpp b/ogr/ogrsf_frmts/plscenes/ogrplscenesdataset.cpp
index 32d9485..b7309d0 100644
--- a/ogr/ogrsf_frmts/plscenes/ogrplscenesdataset.cpp
+++ b/ogr/ogrsf_frmts/plscenes/ogrplscenesdataset.cpp
@@ -29,7 +29,7 @@
 #include "ogr_plscenes.h"
 #include "ogrgeojsonreader.h"
 
-CPL_CVSID("$Id: ogrplscenesdataset.cpp 37371 2017-02-13 11:41:59Z rouault $");
+CPL_CVSID("$Id: ogrplscenesdataset.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 /************************************************************************/
 /*                         OGRPLScenesDataset()                         */
@@ -255,21 +255,13 @@ json_object* OGRPLScenesDataset::RunRequest(const char* pszURL,
         return NULL;
     }
 
-    json_tokener* jstok = NULL;
     json_object* poObj = NULL;
-
-    jstok = json_tokener_new();
-    poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1);
-    if( jstok->err != json_tokener_success)
+    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
+    if( !OGRJSonParse(pszText, &poObj, true) )
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
-                    "JSON parsing error: %s (at offset %d)",
-                    json_tokener_error_desc(jstok->err), jstok->char_offset);
-        json_tokener_free(jstok);
         CPLHTTPDestroyResult(psResult);
         return NULL;
     }
-    json_tokener_free(jstok);
 
     CPLHTTPDestroyResult(psResult);
 
diff --git a/ogr/ogrsf_frmts/plscenes/ogrplscenesdatav1dataset.cpp b/ogr/ogrsf_frmts/plscenes/ogrplscenesdatav1dataset.cpp
index e2872f9..b6c32d8 100644
--- a/ogr/ogrsf_frmts/plscenes/ogrplscenesdatav1dataset.cpp
+++ b/ogr/ogrsf_frmts/plscenes/ogrplscenesdatav1dataset.cpp
@@ -30,7 +30,7 @@
 #include "ogrgeojsonreader.h"
 #include <time.h>
 
-CPL_CVSID("$Id: ogrplscenesdatav1dataset.cpp 37371 2017-02-13 11:41:59Z rouault $");
+CPL_CVSID("$Id: ogrplscenesdatav1dataset.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 /************************************************************************/
 /*                       OGRPLScenesDataV1Dataset()                     */
@@ -335,25 +335,17 @@ json_object* OGRPLScenesDataV1Dataset::RunRequest(const char* pszURL,
         return NULL;
     }
 
-    json_tokener* jstok = NULL;
-    json_object* poObj = NULL;
-
+    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
 #ifdef DEBUG_VERBOSE
-    CPLDebug("PLScenes", "%s", (const char*) psResult->pabyData);
+    CPLDebug("PLScenes", "%s", (pszText);
 #endif
 
-    jstok = json_tokener_new();
-    poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1);
-    if( jstok->err != json_tokener_success)
+    json_object* poObj = NULL;
+    if( !OGRJSonParse(pszText, &poObj, true) )
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
-                    "JSON parsing error: %s (at offset %d)",
-                    json_tokener_error_desc(jstok->err), jstok->char_offset);
-        json_tokener_free(jstok);
         CPLHTTPDestroyResult(psResult);
         return NULL;
     }
-    json_tokener_free(jstok);
 
     CPLHTTPDestroyResult(psResult);
 
diff --git a/ogr/ogrsf_frmts/plscenes/ogrplscenesv1dataset.cpp b/ogr/ogrsf_frmts/plscenes/ogrplscenesv1dataset.cpp
index f74fbd6..63ca619 100644
--- a/ogr/ogrsf_frmts/plscenes/ogrplscenesv1dataset.cpp
+++ b/ogr/ogrsf_frmts/plscenes/ogrplscenesv1dataset.cpp
@@ -30,7 +30,7 @@
 #include "ogrgeojsonreader.h"
 #include <time.h>
 
-CPL_CVSID("$Id: ogrplscenesv1dataset.cpp 37371 2017-02-13 11:41:59Z rouault $");
+CPL_CVSID("$Id: ogrplscenesv1dataset.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 /************************************************************************/
 /*                         OGRPLScenesV1Dataset()                       */
@@ -349,25 +349,17 @@ json_object* OGRPLScenesV1Dataset::RunRequest(const char* pszURL,
         return NULL;
     }
 
-    json_tokener* jstok = NULL;
-    json_object* poObj = NULL;
-
+    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
 #ifdef DEBUG_VERBOSE
-    CPLDebug("PLScenes", "%s", (const char*) psResult->pabyData);
+    CPLDebug("PLScenes", "%s", (pszText);
 #endif
 
-    jstok = json_tokener_new();
-    poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1);
-    if( jstok->err != json_tokener_success)
+    json_object* poObj = NULL;
+    if( !OGRJSonParse(pszText, &poObj, true) )
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
-                    "JSON parsing error: %s (at offset %d)",
-                    json_tokener_error_desc(jstok->err), jstok->char_offset);
-        json_tokener_free(jstok);
         CPLHTTPDestroyResult(psResult);
         return NULL;
     }
-    json_tokener_free(jstok);
 
     CPLHTTPDestroyResult(psResult);
 
diff --git a/ogr/ogrsf_frmts/plscenes/ogrplscenesv1layer.cpp b/ogr/ogrsf_frmts/plscenes/ogrplscenesv1layer.cpp
index 3eddaa1..e533c44 100644
--- a/ogr/ogrsf_frmts/plscenes/ogrplscenesv1layer.cpp
+++ b/ogr/ogrsf_frmts/plscenes/ogrplscenesv1layer.cpp
@@ -30,7 +30,7 @@
 #include "ogrgeojsonreader.h"
 #include <algorithm>
 
-CPL_CVSID("$Id: ogrplscenesv1layer.cpp 37371 2017-02-13 11:41:59Z rouault $");
+CPL_CVSID("$Id: ogrplscenesv1layer.cpp 38115 2017-04-23 07:24:41Z rouault $");
 
 /************************************************************************/
 /*                           GetFieldCount()                            */
@@ -545,14 +545,12 @@ void OGRPLScenesV1Layer::EstablishLayerDefn()
     osPropertiesDesc += "}";
 
     // Prettify description
-    json_tokener* jstok = json_tokener_new();
-    json_object* poPropertiesDesc = json_tokener_parse_ex(jstok, osPropertiesDesc, -1);
-    if( jstok->err == json_tokener_success)
+    json_object* poPropertiesDesc = NULL;
+    if( OGRJSonParse(osPropertiesDesc, &poPropertiesDesc, false) )
     {
         osPropertiesDesc = json_object_to_json_string_ext( poPropertiesDesc, JSON_C_TO_STRING_PRETTY );
         json_object_put(poPropertiesDesc);
     }
-    json_tokener_free(jstok);
 
     SetMetadataItem("FIELDS_DESCRIPTION", osPropertiesDesc.c_str());
 
diff --git a/ogr/ogrsf_frmts/shape/shapefil.h b/ogr/ogrsf_frmts/shape/shapefil.h
index 848a4f8..b41904d 100644
--- a/ogr/ogrsf_frmts/shape/shapefil.h
+++ b/ogr/ogrsf_frmts/shape/shapefil.h
@@ -2,7 +2,7 @@
 #define SHAPEFILE_H_INCLUDED
 
 /******************************************************************************
- * $Id: shapefil.h 36727 2016-12-06 20:04:22Z rouault $
+ * $Id: shapefil.h 37997 2017-04-14 10:20:57Z rouault $
  *
  * Project:  Shapelib
  * Purpose:  Primary include file for Shapelib.
@@ -46,6 +46,12 @@
 
 #ifdef USE_CPL
 #include "cpl_conv.h"
+
+/* Hide shapelib symbols in GDAL builds --with-hide-internal-symbols */
+#if !defined(SHPAPI_CALL) && defined(USE_GCC_VISIBILITY_FLAG)
+#define SHPAPI_CALL
+#endif
+
 #endif
 
 #ifdef __cplusplus
diff --git a/ogr/ogrutils.cpp b/ogr/ogrutils.cpp
index ac442ea..d687a0a 100644
--- a/ogr/ogrutils.cpp
+++ b/ogr/ogrutils.cpp
@@ -48,7 +48,7 @@
 #include "ogr_geometry.h"
 #include "ogrsf_frmts.h"
 
-CPL_CVSID("$Id: ogrutils.cpp 37564 2017-03-03 09:09:26Z rouault $");
+CPL_CVSID("$Id: ogrutils.cpp 38076 2017-04-20 19:37:14Z rouault $");
 
 // Returns whether a double fits within an int.
 // Unable to put this in cpl_port.h as include limit breaks grib.
@@ -1050,12 +1050,16 @@ int OGRParseDate( const char *pszInput,
 
         while( *pszInput >= '0' && *pszInput <= '9' )
             ++pszInput;
+        if( *pszInput == '\0' )
+            return TRUE;
 
         bGotSomething = true;
 
         // If ISO 8601 format.
         if( *pszInput == 'T' )
             ++pszInput;
+        else if( *pszInput != ' ' )
+            return FALSE;
     }
 
 /* -------------------------------------------------------------------- */
diff --git a/port/cpl_string.h b/port/cpl_string.h
index 0a22717..46383c2 100644
--- a/port/cpl_string.h
+++ b/port/cpl_string.h
@@ -1,5 +1,5 @@
 /**********************************************************************
- * $Id: cpl_string.h 37869 2017-03-31 00:15:46Z rouault $
+ * $Id: cpl_string.h 38064 2017-04-19 08:58:09Z rouault $
  *
  * Name:     cpl_string.h
  * Project:  CPL - Common Portability Library
@@ -334,37 +334,8 @@ extern "C++"
 #include <string>
 #endif
 
-/*
- * Simple trick to avoid "using" declaration in header for new compilers
- * but make it still working with old compilers which throw C2614 errors.
- *
- * Define MSVC_OLD_STUPID_BEHAVIOUR
- * for old compilers: VC++ 5 and 6 as well as eVC++ 3 and 4.
- */
-
-/*
- * Detect old MSVC++ compiler <= 6.0
- * 1200 - VC++ 6.0
- * 1200-1202 - eVC++ 4.0
- */
-#if defined(_MSC_VER)
-# if (_MSC_VER <= 1202)
-#  define MSVC_OLD_STUPID_BEHAVIOUR
-# endif
-#endif
-
-/* Avoid C2614 errors */
-#ifdef MSVC_OLD_STUPID_BEHAVIOUR
-    using std::string;
-# define gdal_std_string string
-#else
-/*! @cond Doxygen_Suppress */
-# define gdal_std_string std::string
-/*! @endcond */
-#endif
-
 //! Convenient string class based on std::string.
-class CPL_DLL CPLString : public gdal_std_string
+class CPL_DLL CPLString : public std::string
 {
 public:
 
@@ -372,10 +343,12 @@ public:
     CPLString(void) {}
     /** Constructor */
     // cppcheck-suppress noExplicitConstructor
-    CPLString( const std::string &oStr ) : gdal_std_string( oStr ) {}
+    CPLString( const std::string &oStr ) : std::string( oStr ) {}
     /** Constructor */
     // cppcheck-suppress noExplicitConstructor
-    CPLString( const char *pszStr ) : gdal_std_string( pszStr ) {}
+    CPLString( const char *pszStr ) : std::string( pszStr ) {}
+    /** Constructor */
+    CPLString( const char *pszStr, size_t n ) : std::string( pszStr, n ) {}
 
     /** Return string as zero terminated character array */
     operator const char* (void) const { return c_str(); }
@@ -383,26 +356,26 @@ public:
     /** Return character at specified index */
     char& operator[](std::string::size_type i)
     {
-        return gdal_std_string::operator[](i);
+        return std::string::operator[](i);
     }
 
     /** Return character at specified index */
     const char& operator[](std::string::size_type i) const
     {
-        return gdal_std_string::operator[](i);
+        return std::string::operator[](i);
     }
 
     /** Return character at specified index */
     char& operator[](int i)
     {
-        return gdal_std_string::operator[](
+        return std::string::operator[](
             static_cast<std::string::size_type>(i));
     }
 
     /** Return character at specified index */
     const char& operator[](int i) const
     {
-        return gdal_std_string::operator[](
+        return std::string::operator[](
             static_cast<std::string::size_type>(i));
     }
 
diff --git a/swig/csharp/ogr/Feature.cs b/swig/csharp/ogr/Feature.cs
index 5c15330..15dfca2 100644
--- a/swig/csharp/ogr/Feature.cs
+++ b/swig/csharp/ogr/Feature.cs
@@ -104,8 +104,8 @@ public class Feature : IDisposable {
     return ret;
   }
 
-  public int SetGeomField(string name, Geometry geom) {
-    int ret = OgrPINVOKE.Feature_SetGeomField__SWIG_1(swigCPtr, name, Geometry.getCPtr(geom));
+  public int SetGeomField(string field_name, Geometry geom) {
+    int ret = OgrPINVOKE.Feature_SetGeomField__SWIG_1(swigCPtr, field_name, Geometry.getCPtr(geom));
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
@@ -116,8 +116,8 @@ public class Feature : IDisposable {
     return ret;
   }
 
-  public int SetGeomFieldDirectly(string name, Geometry geom) {
-    int ret = OgrPINVOKE.Feature_SetGeomFieldDirectly__SWIG_1(swigCPtr, name, Geometry.getCPtrAndDisown(geom, ThisOwn_false()));
+  public int SetGeomFieldDirectly(string field_name, Geometry geom) {
+    int ret = OgrPINVOKE.Feature_SetGeomFieldDirectly__SWIG_1(swigCPtr, field_name, Geometry.getCPtrAndDisown(geom, ThisOwn_false()));
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
@@ -129,8 +129,8 @@ public class Feature : IDisposable {
     return ret;
   }
 
-  public Geometry GetGeomFieldRef(string name) {
-    IntPtr cPtr = OgrPINVOKE.Feature_GetGeomFieldRef__SWIG_1(swigCPtr, name);
+  public Geometry GetGeomFieldRef(string field_name) {
+    IntPtr cPtr = OgrPINVOKE.Feature_GetGeomFieldRef__SWIG_1(swigCPtr, field_name);
     Geometry ret = (cPtr == IntPtr.Zero) ? null : new Geometry(cPtr, false, ThisOwn_false());
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
@@ -162,8 +162,8 @@ public class Feature : IDisposable {
     return ret;
   }
 
-  public FieldDefn GetFieldDefnRef(string name) {
-    IntPtr cPtr = OgrPINVOKE.Feature_GetFieldDefnRef__SWIG_1(swigCPtr, name);
+  public FieldDefn GetFieldDefnRef(string field_name) {
+    IntPtr cPtr = OgrPINVOKE.Feature_GetFieldDefnRef__SWIG_1(swigCPtr, field_name);
     FieldDefn ret = (cPtr == IntPtr.Zero) ? null : new FieldDefn(cPtr, false, ThisOwn_false());
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
@@ -182,8 +182,8 @@ public class Feature : IDisposable {
     return ret;
   }
 
-  public GeomFieldDefn GetGeomFieldDefnRef(string name) {
-    IntPtr cPtr = OgrPINVOKE.Feature_GetGeomFieldDefnRef__SWIG_1(swigCPtr, name);
+  public GeomFieldDefn GetGeomFieldDefnRef(string field_name) {
+    IntPtr cPtr = OgrPINVOKE.Feature_GetGeomFieldDefnRef__SWIG_1(swigCPtr, field_name);
     GeomFieldDefn ret = (cPtr == IntPtr.Zero) ? null : new GeomFieldDefn(cPtr, false, ThisOwn_false());
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
@@ -198,9 +198,9 @@ public class Feature : IDisposable {
         return ret;
 }
 
-  public string GetFieldAsString(string name) {
+  public string GetFieldAsString(string field_name) {
         /* %typemap(csout) (const char *utf8_path) */
-        IntPtr cPtr = OgrPINVOKE.Feature_GetFieldAsString__SWIG_1(swigCPtr, name);
+        IntPtr cPtr = OgrPINVOKE.Feature_GetFieldAsString__SWIG_1(swigCPtr, field_name);
         string ret = Ogr.Utf8BytesToString(cPtr);
         
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
@@ -213,8 +213,8 @@ public class Feature : IDisposable {
     return ret;
   }
 
-  public int GetFieldAsInteger(string name) {
-    int ret = OgrPINVOKE.Feature_GetFieldAsInteger__SWIG_1(swigCPtr, name);
+  public int GetFieldAsInteger(string field_name) {
+    int ret = OgrPINVOKE.Feature_GetFieldAsInteger__SWIG_1(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
@@ -225,8 +225,8 @@ public class Feature : IDisposable {
     return res;
 }
 
-  public long GetFieldAsInteger64(string name) {
-    long res = OgrPINVOKE.Feature_GetFieldAsInteger64__SWIG_1(swigCPtr, name);
+  public long GetFieldAsInteger64(string field_name) {
+    long res = OgrPINVOKE.Feature_GetFieldAsInteger64__SWIG_1(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return res;
 }
@@ -237,8 +237,8 @@ public class Feature : IDisposable {
     return ret;
   }
 
-  public double GetFieldAsDouble(string name) {
-    double ret = OgrPINVOKE.Feature_GetFieldAsDouble__SWIG_1(swigCPtr, name);
+  public double GetFieldAsDouble(string field_name) {
+    double ret = OgrPINVOKE.Feature_GetFieldAsDouble__SWIG_1(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
@@ -248,8 +248,8 @@ public class Feature : IDisposable {
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
-  public void GetFieldAsDateTime(string name, out int pnYear, out int pnMonth, out int pnDay, out int pnHour, out int pnMinute, out float pfSecond, out int pnTZFlag) {
-    OgrPINVOKE.Feature_GetFieldAsDateTime__SWIG_1(swigCPtr, name, out pnYear, out pnMonth, out pnDay, out pnHour, out pnMinute, out pfSecond, out pnTZFlag);
+  public void GetFieldAsDateTime(string field_name, out int pnYear, out int pnMonth, out int pnDay, out int pnHour, out int pnMinute, out float pfSecond, out int pnTZFlag) {
+    OgrPINVOKE.Feature_GetFieldAsDateTime__SWIG_1(swigCPtr, field_name, out pnYear, out pnMonth, out pnDay, out pnHour, out pnMinute, out pfSecond, out pnTZFlag);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
@@ -304,8 +304,8 @@ public class Feature : IDisposable {
     return ret;
   }
 
-  public bool IsFieldSet(string name) {
-    bool ret = OgrPINVOKE.Feature_IsFieldSet__SWIG_1(swigCPtr, name);
+  public bool IsFieldSet(string field_name) {
+    bool ret = OgrPINVOKE.Feature_IsFieldSet__SWIG_1(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
@@ -316,8 +316,8 @@ public class Feature : IDisposable {
     return ret;
   }
 
-  public bool IsFieldNull(string name) {
-    bool ret = OgrPINVOKE.Feature_IsFieldNull__SWIG_1(swigCPtr, name);
+  public bool IsFieldNull(string field_name) {
+    bool ret = OgrPINVOKE.Feature_IsFieldNull__SWIG_1(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
@@ -328,20 +328,20 @@ public class Feature : IDisposable {
     return ret;
   }
 
-  public bool IsFieldSetAndNotNull(string name) {
-    bool ret = OgrPINVOKE.Feature_IsFieldSetAndNotNull__SWIG_1(swigCPtr, name);
+  public bool IsFieldSetAndNotNull(string field_name) {
+    bool ret = OgrPINVOKE.Feature_IsFieldSetAndNotNull__SWIG_1(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
 
-  public int GetFieldIndex(string name) {
-    int ret = OgrPINVOKE.Feature_GetFieldIndex(swigCPtr, name);
+  public int GetFieldIndex(string field_name) {
+    int ret = OgrPINVOKE.Feature_GetFieldIndex(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
 
-  public int GetGeomFieldIndex(string name) {
-    int ret = OgrPINVOKE.Feature_GetGeomFieldIndex(swigCPtr, name);
+  public int GetGeomFieldIndex(string field_name) {
+    int ret = OgrPINVOKE.Feature_GetGeomFieldIndex(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
@@ -368,8 +368,8 @@ public class Feature : IDisposable {
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
-  public void UnsetField(string name) {
-    OgrPINVOKE.Feature_UnsetField__SWIG_1(swigCPtr, name);
+  public void UnsetField(string field_name) {
+    OgrPINVOKE.Feature_UnsetField__SWIG_1(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
@@ -378,8 +378,8 @@ public class Feature : IDisposable {
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
-  public void SetFieldNull(string name) {
-    OgrPINVOKE.Feature_SetFieldNull__SWIG_1(swigCPtr, name);
+  public void SetFieldNull(string field_name) {
+    OgrPINVOKE.Feature_SetFieldNull__SWIG_1(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
@@ -388,8 +388,8 @@ public class Feature : IDisposable {
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
-  public void SetField(string name, string value) {
-    OgrPINVOKE.Feature_SetField__SWIG_1(swigCPtr, name, Ogr.StringToUtf8Bytes(value));
+  public void SetField(string field_name, string value) {
+    OgrPINVOKE.Feature_SetField__SWIG_1(swigCPtr, field_name, Ogr.StringToUtf8Bytes(value));
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
@@ -403,8 +403,8 @@ public class Feature : IDisposable {
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
-  public void SetField(string name, int value) {
-    OgrPINVOKE.Feature_SetField__SWIG_3(swigCPtr, name, value);
+  public void SetField(string field_name, int value) {
+    OgrPINVOKE.Feature_SetField__SWIG_3(swigCPtr, field_name, value);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
@@ -413,8 +413,8 @@ public class Feature : IDisposable {
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
-  public void SetField(string name, double value) {
-    OgrPINVOKE.Feature_SetField__SWIG_5(swigCPtr, name, value);
+  public void SetField(string field_name, double value) {
+    OgrPINVOKE.Feature_SetField__SWIG_5(swigCPtr, field_name, value);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
@@ -423,8 +423,8 @@ public class Feature : IDisposable {
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
-  public void SetField(string name, int year, int month, int day, int hour, int minute, float second, int tzflag) {
-    OgrPINVOKE.Feature_SetField__SWIG_7(swigCPtr, name, year, month, day, hour, minute, second, tzflag);
+  public void SetField(string field_name, int year, int month, int day, int hour, int minute, float second, int tzflag) {
+    OgrPINVOKE.Feature_SetField__SWIG_7(swigCPtr, field_name, year, month, day, hour, minute, second, tzflag);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
@@ -448,8 +448,8 @@ public class Feature : IDisposable {
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
-  public void SetFieldBinaryFromHexString(string name, string pszValue) {
-    OgrPINVOKE.Feature_SetFieldBinaryFromHexString__SWIG_1(swigCPtr, name, pszValue);
+  public void SetFieldBinaryFromHexString(string field_name, string pszValue) {
+    OgrPINVOKE.Feature_SetFieldBinaryFromHexString__SWIG_1(swigCPtr, field_name, pszValue);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
   }
 
@@ -482,8 +482,8 @@ public class Feature : IDisposable {
     return ret;
   }
 
-  public FieldType GetFieldType(string name) {
-    FieldType ret = (FieldType)OgrPINVOKE.Feature_GetFieldType__SWIG_1(swigCPtr, name);
+  public FieldType GetFieldType(string field_name) {
+    FieldType ret = (FieldType)OgrPINVOKE.Feature_GetFieldType__SWIG_1(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
diff --git a/swig/csharp/ogr/FeatureDefn.cs b/swig/csharp/ogr/FeatureDefn.cs
index 17efd22..fba81ee 100644
--- a/swig/csharp/ogr/FeatureDefn.cs
+++ b/swig/csharp/ogr/FeatureDefn.cs
@@ -91,8 +91,8 @@ public class FeatureDefn : IDisposable {
     return ret;
   }
 
-  public int GetFieldIndex(string name) {
-    int ret = OgrPINVOKE.FeatureDefn_GetFieldIndex(swigCPtr, name);
+  public int GetFieldIndex(string field_name) {
+    int ret = OgrPINVOKE.FeatureDefn_GetFieldIndex(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
@@ -115,8 +115,8 @@ public class FeatureDefn : IDisposable {
     return ret;
   }
 
-  public int GetGeomFieldIndex(string name) {
-    int ret = OgrPINVOKE.FeatureDefn_GetGeomFieldIndex(swigCPtr, name);
+  public int GetGeomFieldIndex(string field_name) {
+    int ret = OgrPINVOKE.FeatureDefn_GetGeomFieldIndex(swigCPtr, field_name);
     if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
diff --git a/swig/csharp/ogr/ogr_wrap.cpp b/swig/csharp/ogr/ogr_wrap.cpp
index a07ac96..69b79f1 100644
--- a/swig/csharp/ogr/ogr_wrap.cpp
+++ b/swig/csharp/ogr/ogr_wrap.cpp
@@ -749,11 +749,11 @@ SWIGINTERN OGRGeometryShadow *OGRFeatureShadow_GetGeometryRef(OGRFeatureShadow *
 SWIGINTERN OGRErr OGRFeatureShadow_SetGeomField__SWIG_0(OGRFeatureShadow *self,int iField,OGRGeometryShadow *geom){
     return OGR_F_SetGeomField(self, iField, geom);
   }
-SWIGINTERN OGRErr OGRFeatureShadow_SetGeomField__SWIG_1(OGRFeatureShadow *self,char const *name,OGRGeometryShadow *geom){
-      int iField = OGR_F_GetGeomFieldIndex(self, name);
+SWIGINTERN OGRErr OGRFeatureShadow_SetGeomField__SWIG_1(OGRFeatureShadow *self,char const *field_name,OGRGeometryShadow *geom){
+      int iField = OGR_F_GetGeomFieldIndex(self, field_name);
       if (iField == -1)
       {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return 6;
       }
       else
@@ -762,11 +762,11 @@ SWIGINTERN OGRErr OGRFeatureShadow_SetGeomField__SWIG_1(OGRFeatureShadow *self,c
 SWIGINTERN OGRErr OGRFeatureShadow_SetGeomFieldDirectly__SWIG_0(OGRFeatureShadow *self,int iField,OGRGeometryShadow *geom){
     return OGR_F_SetGeomFieldDirectly(self, iField, geom);
   }
-SWIGINTERN OGRErr OGRFeatureShadow_SetGeomFieldDirectly__SWIG_1(OGRFeatureShadow *self,char const *name,OGRGeometryShadow *geom){
-      int iField = OGR_F_GetGeomFieldIndex(self, name);
+SWIGINTERN OGRErr OGRFeatureShadow_SetGeomFieldDirectly__SWIG_1(OGRFeatureShadow *self,char const *field_name,OGRGeometryShadow *geom){
+      int iField = OGR_F_GetGeomFieldIndex(self, field_name);
       if (iField == -1)
       {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return 6;
       }
       else
@@ -775,11 +775,11 @@ SWIGINTERN OGRErr OGRFeatureShadow_SetGeomFieldDirectly__SWIG_1(OGRFeatureShadow
 SWIGINTERN OGRGeometryShadow *OGRFeatureShadow_GetGeomFieldRef__SWIG_0(OGRFeatureShadow *self,int iField){
     return (OGRGeometryShadow*) OGR_F_GetGeomFieldRef(self, iField);
   }
-SWIGINTERN OGRGeometryShadow *OGRFeatureShadow_GetGeomFieldRef__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetGeomFieldIndex(self, name);
+SWIGINTERN OGRGeometryShadow *OGRFeatureShadow_GetGeomFieldRef__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetGeomFieldIndex(self, field_name);
       if (i == -1)
       {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return NULL;
       }
       else
@@ -797,10 +797,10 @@ SWIGINTERN int OGRFeatureShadow_GetFieldCount(OGRFeatureShadow *self){
 SWIGINTERN OGRFieldDefnShadow *OGRFeatureShadow_GetFieldDefnRef__SWIG_0(OGRFeatureShadow *self,int id){
     return (OGRFieldDefnShadow *) OGR_F_GetFieldDefnRef(self, id);
   }
-SWIGINTERN OGRFieldDefnShadow *OGRFeatureShadow_GetFieldDefnRef__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN OGRFieldDefnShadow *OGRFeatureShadow_GetFieldDefnRef__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           return (OGRFieldDefnShadow *) OGR_F_GetFieldDefnRef(self, i);
       return NULL;
@@ -811,10 +811,10 @@ SWIGINTERN int OGRFeatureShadow_GetGeomFieldCount(OGRFeatureShadow *self){
 SWIGINTERN OGRGeomFieldDefnShadow *OGRFeatureShadow_GetGeomFieldDefnRef__SWIG_0(OGRFeatureShadow *self,int id){
       return (OGRGeomFieldDefnShadow *) OGR_F_GetGeomFieldDefnRef(self, id);
   }
-SWIGINTERN OGRGeomFieldDefnShadow *OGRFeatureShadow_GetGeomFieldDefnRef__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetGeomFieldIndex(self, name);
+SWIGINTERN OGRGeomFieldDefnShadow *OGRFeatureShadow_GetGeomFieldDefnRef__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetGeomFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           return (OGRGeomFieldDefnShadow *) OGR_F_GetGeomFieldDefnRef(self, i);
       return NULL;
@@ -822,10 +822,10 @@ SWIGINTERN OGRGeomFieldDefnShadow *OGRFeatureShadow_GetGeomFieldDefnRef__SWIG_1(
 SWIGINTERN char const *OGRFeatureShadow_GetFieldAsString__SWIG_0(OGRFeatureShadow *self,int id){
     return (const char *) OGR_F_GetFieldAsString(self, id);
   }
-SWIGINTERN char const *OGRFeatureShadow_GetFieldAsString__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN char const *OGRFeatureShadow_GetFieldAsString__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return (const char *) OGR_F_GetFieldAsString(self, i);
       return NULL;
@@ -833,10 +833,10 @@ SWIGINTERN char const *OGRFeatureShadow_GetFieldAsString__SWIG_1(OGRFeatureShado
 SWIGINTERN int OGRFeatureShadow_GetFieldAsInteger__SWIG_0(OGRFeatureShadow *self,int id){
     return OGR_F_GetFieldAsInteger(self, id);
   }
-SWIGINTERN int OGRFeatureShadow_GetFieldAsInteger__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN int OGRFeatureShadow_GetFieldAsInteger__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return OGR_F_GetFieldAsInteger(self, i);
       return 0;
@@ -844,10 +844,10 @@ SWIGINTERN int OGRFeatureShadow_GetFieldAsInteger__SWIG_1(OGRFeatureShadow *self
 SWIGINTERN GIntBig OGRFeatureShadow_GetFieldAsInteger64__SWIG_0(OGRFeatureShadow *self,int id){
     return OGR_F_GetFieldAsInteger64(self, id);
   }
-SWIGINTERN GIntBig OGRFeatureShadow_GetFieldAsInteger64__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN GIntBig OGRFeatureShadow_GetFieldAsInteger64__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           return OGR_F_GetFieldAsInteger64(self, i);
       return 0;
@@ -855,10 +855,10 @@ SWIGINTERN GIntBig OGRFeatureShadow_GetFieldAsInteger64__SWIG_1(OGRFeatureShadow
 SWIGINTERN double OGRFeatureShadow_GetFieldAsDouble__SWIG_0(OGRFeatureShadow *self,int id){
     return OGR_F_GetFieldAsDouble(self, id);
   }
-SWIGINTERN double OGRFeatureShadow_GetFieldAsDouble__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN double OGRFeatureShadow_GetFieldAsDouble__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           return OGR_F_GetFieldAsDouble(self, i);
       return 0;
@@ -868,10 +868,10 @@ SWIGINTERN void OGRFeatureShadow_GetFieldAsDateTime__SWIG_0(OGRFeatureShadow *se
 			       pnHour, pnMinute, pfSecond,
 			       pnTZFlag);
   }
-SWIGINTERN void OGRFeatureShadow_GetFieldAsDateTime__SWIG_1(OGRFeatureShadow *self,char const *name,int *pnYear,int *pnMonth,int *pnDay,int *pnHour,int *pnMinute,float *pfSecond,int *pnTZFlag){
-      int id = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_GetFieldAsDateTime__SWIG_1(OGRFeatureShadow *self,char const *field_name,int *pnYear,int *pnMonth,int *pnDay,int *pnHour,int *pnMinute,float *pfSecond,int *pnTZFlag){
+      int id = OGR_F_GetFieldIndex(self, field_name);
       if (id == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  OGR_F_GetFieldAsDateTimeEx(self, id, pnYear, pnMonth, pnDay,
 			       pnHour, pnMinute, pfSecond,
@@ -889,10 +889,10 @@ SWIGINTERN char **OGRFeatureShadow_GetFieldAsStringList(OGRFeatureShadow *self,i
 SWIGINTERN bool OGRFeatureShadow_IsFieldSet__SWIG_0(OGRFeatureShadow *self,int id){
     return (OGR_F_IsFieldSet(self, id) > 0);
   }
-SWIGINTERN bool OGRFeatureShadow_IsFieldSet__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN bool OGRFeatureShadow_IsFieldSet__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return (OGR_F_IsFieldSet(self, i) > 0);
       return false;
@@ -900,10 +900,10 @@ SWIGINTERN bool OGRFeatureShadow_IsFieldSet__SWIG_1(OGRFeatureShadow *self,char
 SWIGINTERN bool OGRFeatureShadow_IsFieldNull__SWIG_0(OGRFeatureShadow *self,int id){
     return (OGR_F_IsFieldNull(self, id) > 0);
   }
-SWIGINTERN bool OGRFeatureShadow_IsFieldNull__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN bool OGRFeatureShadow_IsFieldNull__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return (OGR_F_IsFieldNull(self, i) > 0);
       return false;
@@ -911,21 +911,21 @@ SWIGINTERN bool OGRFeatureShadow_IsFieldNull__SWIG_1(OGRFeatureShadow *self,char
 SWIGINTERN bool OGRFeatureShadow_IsFieldSetAndNotNull__SWIG_0(OGRFeatureShadow *self,int id){
     return (OGR_F_IsFieldSetAndNotNull(self, id) > 0);
   }
-SWIGINTERN bool OGRFeatureShadow_IsFieldSetAndNotNull__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN bool OGRFeatureShadow_IsFieldSetAndNotNull__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return (OGR_F_IsFieldSetAndNotNull(self, i) > 0);
       return false;
   }
-SWIGINTERN int OGRFeatureShadow_GetFieldIndex(OGRFeatureShadow *self,char const *name){
+SWIGINTERN int OGRFeatureShadow_GetFieldIndex(OGRFeatureShadow *self,char const *field_name){
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_F_GetFieldIndex(self, name);
+      return OGR_F_GetFieldIndex(self, field_name);
   }
-SWIGINTERN int OGRFeatureShadow_GetGeomFieldIndex(OGRFeatureShadow *self,char const *name){
+SWIGINTERN int OGRFeatureShadow_GetGeomFieldIndex(OGRFeatureShadow *self,char const *field_name){
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_F_GetGeomFieldIndex(self, name);
+      return OGR_F_GetGeomFieldIndex(self, field_name);
   }
 SWIGINTERN GIntBig OGRFeatureShadow_GetFID(OGRFeatureShadow *self){
     return OGR_F_GetFID(self);
@@ -939,30 +939,30 @@ SWIGINTERN void OGRFeatureShadow_DumpReadable(OGRFeatureShadow *self){
 SWIGINTERN void OGRFeatureShadow_UnsetField__SWIG_0(OGRFeatureShadow *self,int id){
     OGR_F_UnsetField(self, id);
   }
-SWIGINTERN void OGRFeatureShadow_UnsetField__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_UnsetField__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           OGR_F_UnsetField(self, i);
   }
 SWIGINTERN void OGRFeatureShadow_SetFieldNull__SWIG_0(OGRFeatureShadow *self,int id){
     OGR_F_SetFieldNull(self, id);
   }
-SWIGINTERN void OGRFeatureShadow_SetFieldNull__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_SetFieldNull__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           OGR_F_SetFieldNull(self, i);
   }
 SWIGINTERN void OGRFeatureShadow_SetField__SWIG_0(OGRFeatureShadow *self,int id,char const *value){
     OGR_F_SetFieldString(self, id, value);
   }
-SWIGINTERN void OGRFeatureShadow_SetField__SWIG_1(OGRFeatureShadow *self,char const *name,char const *value){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_SetField__SWIG_1(OGRFeatureShadow *self,char const *field_name,char const *value){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           OGR_F_SetFieldString(self, i, value);
   }
@@ -972,20 +972,20 @@ SWIGINTERN void OGRFeatureShadow_SetFieldInteger64(OGRFeatureShadow *self,int id
 SWIGINTERN void OGRFeatureShadow_SetField__SWIG_2(OGRFeatureShadow *self,int id,int value){
     OGR_F_SetFieldInteger(self, id, value);
   }
-SWIGINTERN void OGRFeatureShadow_SetField__SWIG_3(OGRFeatureShadow *self,char const *name,int value){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_SetField__SWIG_3(OGRFeatureShadow *self,char const *field_name,int value){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  OGR_F_SetFieldInteger(self, i, value);
   }
 SWIGINTERN void OGRFeatureShadow_SetField__SWIG_4(OGRFeatureShadow *self,int id,double value){
     OGR_F_SetFieldDouble(self, id, value);
   }
-SWIGINTERN void OGRFeatureShadow_SetField__SWIG_5(OGRFeatureShadow *self,char const *name,double value){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_SetField__SWIG_5(OGRFeatureShadow *self,char const *field_name,double value){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  OGR_F_SetFieldDouble(self, i, value);
   }
@@ -994,10 +994,10 @@ SWIGINTERN void OGRFeatureShadow_SetField__SWIG_6(OGRFeatureShadow *self,int id,
                              hour, minute, second,
                              tzflag);
   }
-SWIGINTERN void OGRFeatureShadow_SetField__SWIG_7(OGRFeatureShadow *self,char const *name,int year,int month,int day,int hour,int minute,float second,int tzflag){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_SetField__SWIG_7(OGRFeatureShadow *self,char const *field_name,int year,int month,int day,int hour,int minute,float second,int tzflag){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  OGR_F_SetFieldDateTimeEx(self, i, year, month, day,
 				 hour, minute, second,
@@ -1018,10 +1018,10 @@ SWIGINTERN void OGRFeatureShadow_SetFieldBinaryFromHexString__SWIG_0(OGRFeatureS
      OGR_F_SetFieldBinary(self, id, nBytes, pabyBuf);
      CPLFree(pabyBuf);
   }
-SWIGINTERN void OGRFeatureShadow_SetFieldBinaryFromHexString__SWIG_1(OGRFeatureShadow *self,char const *name,char const *pszValue){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_SetFieldBinaryFromHexString__SWIG_1(OGRFeatureShadow *self,char const *field_name,char const *pszValue){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
       {
           int nBytes;
@@ -1055,10 +1055,10 @@ SWIGINTERN OGRFieldType OGRFeatureShadow_GetFieldType__SWIG_0(OGRFeatureShadow *
       else
           return (OGRFieldType)0;
   }
-SWIGINTERN OGRFieldType OGRFeatureShadow_GetFieldType__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN OGRFieldType OGRFeatureShadow_GetFieldType__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1) {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return (OGRFieldType)0;
       } else
           return (OGRFieldType) OGR_Fld_GetType( OGR_F_GetFieldDefnRef( self, i ) );
@@ -1182,9 +1182,9 @@ SWIGINTERN int OGRFeatureDefnShadow_GetFieldCount(OGRFeatureDefnShadow *self){
 SWIGINTERN OGRFieldDefnShadow *OGRFeatureDefnShadow_GetFieldDefn(OGRFeatureDefnShadow *self,int i){
     return (OGRFieldDefnShadow*) OGR_FD_GetFieldDefn(self, i);
   }
-SWIGINTERN int OGRFeatureDefnShadow_GetFieldIndex(OGRFeatureDefnShadow *self,char const *name){
+SWIGINTERN int OGRFeatureDefnShadow_GetFieldIndex(OGRFeatureDefnShadow *self,char const *field_name){
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_FD_GetFieldIndex(self, name);
+      return OGR_FD_GetFieldIndex(self, field_name);
   }
 SWIGINTERN void OGRFeatureDefnShadow_AddFieldDefn(OGRFeatureDefnShadow *self,OGRFieldDefnShadow *defn){
     OGR_FD_AddFieldDefn(self, defn);
@@ -1195,9 +1195,9 @@ SWIGINTERN int OGRFeatureDefnShadow_GetGeomFieldCount(OGRFeatureDefnShadow *self
 SWIGINTERN OGRGeomFieldDefnShadow *OGRFeatureDefnShadow_GetGeomFieldDefn(OGRFeatureDefnShadow *self,int i){
     return (OGRGeomFieldDefnShadow*) OGR_FD_GetGeomFieldDefn(self, i);
   }
-SWIGINTERN int OGRFeatureDefnShadow_GetGeomFieldIndex(OGRFeatureDefnShadow *self,char const *name){
+SWIGINTERN int OGRFeatureDefnShadow_GetGeomFieldIndex(OGRFeatureDefnShadow *self,char const *field_name){
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_FD_GetGeomFieldIndex(self, name);
+      return OGR_FD_GetGeomFieldIndex(self, field_name);
   }
 SWIGINTERN void OGRFeatureDefnShadow_AddGeomFieldDefn(OGRFeatureDefnShadow *self,OGRGeomFieldDefnShadow *defn){
     OGR_FD_AddGeomFieldDefn(self, defn);
@@ -6218,13 +6218,6 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Feature_SetGeomField__SWIG_1(void * jarg1, cha
   arg2 = (char *)jarg2; 
   arg3 = (OGRGeometryShadow *)jarg3; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (OGRErr)OGRFeatureShadow_SetGeomField__SWIG_1(arg1,(char const *)arg2,arg3);
     CPLErr eclass = CPLGetLastErrorType();
@@ -6313,13 +6306,6 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Feature_SetGeomFieldDirectly__SWIG_1(void * ja
   arg2 = (char *)jarg2; 
   arg3 = (OGRGeometryShadow *)jarg3; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (OGRErr)OGRFeatureShadow_SetGeomFieldDirectly__SWIG_1(arg1,(char const *)arg2,arg3);
     CPLErr eclass = CPLGetLastErrorType();
@@ -6397,13 +6383,6 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_Feature_GetGeomFieldRef__SWIG_1(void * jarg
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (OGRGeometryShadow *)OGRFeatureShadow_GetGeomFieldRef__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -6582,13 +6561,6 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_Feature_GetFieldDefnRef__SWIG_1(void * jarg
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (OGRFieldDefnShadow *)OGRFeatureShadow_GetFieldDefnRef__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -6692,13 +6664,6 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_Feature_GetGeomFieldDefnRef__SWIG_1(void *
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (OGRGeomFieldDefnShadow *)OGRFeatureShadow_GetGeomFieldDefnRef__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -6769,13 +6734,6 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_Feature_GetFieldAsString__SWIG_1(void * jar
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (char *)OGRFeatureShadow_GetFieldAsString__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -6846,13 +6804,6 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Feature_GetFieldAsInteger__SWIG_1(void * jarg1
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (int)OGRFeatureShadow_GetFieldAsInteger__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -6923,13 +6874,6 @@ SWIGEXPORT GIntBig SWIGSTDCALL CSharp_Feature_GetFieldAsInteger64__SWIG_1(void *
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = OGRFeatureShadow_GetFieldAsInteger64__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -7000,13 +6944,6 @@ SWIGEXPORT double SWIGSTDCALL CSharp_Feature_GetFieldAsDouble__SWIG_1(void * jar
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (double)OGRFeatureShadow_GetFieldAsDouble__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -7099,13 +7036,6 @@ SWIGEXPORT void SWIGSTDCALL CSharp_Feature_GetFieldAsDateTime__SWIG_1(void * jar
   arg8 = (float *)jarg8; 
   arg9 = (int *)jarg9; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return ; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     OGRFeatureShadow_GetFieldAsDateTime__SWIG_1(arg1,(char const *)arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9);
     CPLErr eclass = CPLGetLastErrorType();
@@ -7289,13 +7219,6 @@ SWIGEXPORT unsigned int SWIGSTDCALL CSharp_Feature_IsFieldSet__SWIG_1(void * jar
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (bool)OGRFeatureShadow_IsFieldSet__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -7366,13 +7289,6 @@ SWIGEXPORT unsigned int SWIGSTDCALL CSharp_Feature_IsFieldNull__SWIG_1(void * ja
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (bool)OGRFeatureShadow_IsFieldNull__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -7443,13 +7359,6 @@ SWIGEXPORT unsigned int SWIGSTDCALL CSharp_Feature_IsFieldSetAndNotNull__SWIG_1(
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (bool)OGRFeatureShadow_IsFieldSetAndNotNull__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -7485,13 +7394,6 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Feature_GetFieldIndex(void * jarg1, char * jar
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (int)OGRFeatureShadow_GetFieldIndex(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -7527,13 +7429,6 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Feature_GetGeomFieldIndex(void * jarg1, char *
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (int)OGRFeatureShadow_GetGeomFieldIndex(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -7702,13 +7597,6 @@ SWIGEXPORT void SWIGSTDCALL CSharp_Feature_UnsetField__SWIG_1(void * jarg1, char
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return ; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     OGRFeatureShadow_UnsetField__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -7771,13 +7659,6 @@ SWIGEXPORT void SWIGSTDCALL CSharp_Feature_SetFieldNull__SWIG_1(void * jarg1, ch
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return ; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     OGRFeatureShadow_SetFieldNull__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -7844,13 +7725,6 @@ SWIGEXPORT void SWIGSTDCALL CSharp_Feature_SetField__SWIG_1(void * jarg1, char *
   arg2 = (char *)jarg2; 
   arg3 = (char *)jarg3; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return ; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     OGRFeatureShadow_SetField__SWIG_1(arg1,(char const *)arg2,(char const *)arg3);
     CPLErr eclass = CPLGetLastErrorType();
@@ -7950,13 +7824,6 @@ SWIGEXPORT void SWIGSTDCALL CSharp_Feature_SetField__SWIG_3(void * jarg1, char *
   arg2 = (char *)jarg2; 
   arg3 = (int)jarg3; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return ; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     OGRFeatureShadow_SetField__SWIG_3(arg1,(char const *)arg2,arg3);
     CPLErr eclass = CPLGetLastErrorType();
@@ -8023,13 +7890,6 @@ SWIGEXPORT void SWIGSTDCALL CSharp_Feature_SetField__SWIG_5(void * jarg1, char *
   arg2 = (char *)jarg2; 
   arg3 = (double)jarg3; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return ; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     OGRFeatureShadow_SetField__SWIG_5(arg1,(char const *)arg2,arg3);
     CPLErr eclass = CPLGetLastErrorType();
@@ -8120,13 +7980,6 @@ SWIGEXPORT void SWIGSTDCALL CSharp_Feature_SetField__SWIG_7(void * jarg1, char *
   arg8 = (float)jarg8; 
   arg9 = (int)jarg9; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return ; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     OGRFeatureShadow_SetField__SWIG_7(arg1,(char const *)arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9);
     CPLErr eclass = CPLGetLastErrorType();
@@ -8302,13 +8155,6 @@ SWIGEXPORT void SWIGSTDCALL CSharp_Feature_SetFieldBinaryFromHexString__SWIG_1(v
   arg2 = (char *)jarg2; 
   arg3 = (char *)jarg3; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return ; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     OGRFeatureShadow_SetFieldBinaryFromHexString__SWIG_1(arg1,(char const *)arg2,(char const *)arg3);
     CPLErr eclass = CPLGetLastErrorType();
@@ -8550,13 +8396,6 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Feature_GetFieldType__SWIG_1(void * jarg1, cha
   arg1 = (OGRFeatureShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (OGRFieldType)OGRFeatureShadow_GetFieldType__SWIG_1(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -8953,13 +8792,6 @@ SWIGEXPORT int SWIGSTDCALL CSharp_FeatureDefn_GetFieldIndex(void * jarg1, char *
   arg1 = (OGRFeatureDefnShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (int)OGRFeatureDefnShadow_GetFieldIndex(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
@@ -9101,13 +8933,6 @@ SWIGEXPORT int SWIGSTDCALL CSharp_FeatureDefn_GetGeomFieldIndex(void * jarg1, ch
   arg1 = (OGRFeatureDefnShadow *)jarg1; 
   arg2 = (char *)jarg2; 
   {
-    if (!arg2) {
-      {
-        SWIG_CSharpException(SWIG_ValueError, "Received a NULL pointer."); return 0; 
-      };
-    }
-  }
-  {
     CPLErrorReset();
     result = (int)OGRFeatureDefnShadow_GetGeomFieldIndex(arg1,(char const *)arg2);
     CPLErr eclass = CPLGetLastErrorType();
diff --git a/swig/include/ogr.i b/swig/include/ogr.i
index e90ebf1..9b54d47 100644
--- a/swig/include/ogr.i
+++ b/swig/include/ogr.i
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: ogr.i 37371 2017-02-13 11:41:59Z rouault $
+ * $Id: ogr.i 38101 2017-04-22 16:49:11Z rouault $
  *
  * Project:  OGR Core SWIG Interface declarations.
  * Purpose:  OGR declarations.
@@ -1213,6 +1213,11 @@ typedef double* retDoubleArray;
 %}
 #endif
 
+#ifdef SWIGPYTHON
+/* Applies perhaps to other bindings */
+%apply ( const char *utf8_path ) { (const char* field_name) };
+#endif
+
 %rename (Feature) OGRFeatureShadow;
 class OGRFeatureShadow {
   OGRFeatureShadow();
@@ -1256,11 +1261,11 @@ public:
     return OGR_F_SetGeomField(self, iField, geom);
   }
 
-  OGRErr SetGeomField(const char* name, OGRGeometryShadow* geom) {
-      int iField = OGR_F_GetGeomFieldIndex(self, name);
+  OGRErr SetGeomField(const char* field_name, OGRGeometryShadow* geom) {
+      int iField = OGR_F_GetGeomFieldIndex(self, field_name);
       if (iField == -1)
       {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return OGRERR_FAILURE;
       }
       else
@@ -1274,11 +1279,11 @@ public:
     return OGR_F_SetGeomFieldDirectly(self, iField, geom);
   }
 
-  OGRErr SetGeomFieldDirectly(const char* name, OGRGeometryShadow* geom) {
-      int iField = OGR_F_GetGeomFieldIndex(self, name);
+  OGRErr SetGeomFieldDirectly(const char* field_name, OGRGeometryShadow* geom) {
+      int iField = OGR_F_GetGeomFieldIndex(self, field_name);
       if (iField == -1)
       {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return OGRERR_FAILURE;
       }
       else
@@ -1292,11 +1297,11 @@ public:
   }
 
   /* Feature owns its geometry */
-  OGRGeometryShadow *GetGeomFieldRef(const char* name) {
-      int i = OGR_F_GetGeomFieldIndex(self, name);
+  OGRGeometryShadow *GetGeomFieldRef(const char* field_name) {
+      int i = OGR_F_GetGeomFieldIndex(self, field_name);
       if (i == -1)
       {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return NULL;
       }
       else
@@ -1324,10 +1329,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  OGRFieldDefnShadow *GetFieldDefnRef(const char* name) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  OGRFieldDefnShadow *GetFieldDefnRef(const char* field_name) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           return (OGRFieldDefnShadow *) OGR_F_GetFieldDefnRef(self, i);
       return NULL;
@@ -1345,10 +1350,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  OGRGeomFieldDefnShadow *GetGeomFieldDefnRef(const char* name) {
-      int i = OGR_F_GetGeomFieldIndex(self, name);
+  OGRGeomFieldDefnShadow *GetGeomFieldDefnRef(const char* field_name) {
+      int i = OGR_F_GetGeomFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           return (OGRGeomFieldDefnShadow *) OGR_F_GetGeomFieldDefnRef(self, i);
       return NULL;
@@ -1363,10 +1368,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  const char* GetFieldAsString(const char* name) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  const char* GetFieldAsString(const char* field_name) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return (const char *) OGR_F_GetFieldAsString(self, i);
       return NULL;
@@ -1381,10 +1386,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  int GetFieldAsInteger(const char* name) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  int GetFieldAsInteger(const char* field_name) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return OGR_F_GetFieldAsInteger(self, i);
       return 0;
@@ -1399,10 +1404,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  GIntBig GetFieldAsInteger64(const char* name) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  GIntBig GetFieldAsInteger64(const char* field_name) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           return OGR_F_GetFieldAsInteger64(self, i);
       return 0;
@@ -1417,10 +1422,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  double GetFieldAsDouble(const char* name) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  double GetFieldAsDouble(const char* field_name) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           return OGR_F_GetFieldAsDouble(self, i);
       return 0;
@@ -1438,12 +1443,12 @@ public:
 			       pnTZFlag);
   }
 #ifndef SWIGPERL
-  void GetFieldAsDateTime(const char* name, int *pnYear, int *pnMonth, int *pnDay,
+  void GetFieldAsDateTime(const char* field_name, int *pnYear, int *pnMonth, int *pnDay,
 			  int *pnHour, int *pnMinute, float *pfSecond,
 			  int *pnTZFlag) {
-      int id = OGR_F_GetFieldIndex(self, name);
+      int id = OGR_F_GetFieldIndex(self, field_name);
       if (id == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  OGR_F_GetFieldAsDateTimeEx(self, id, pnYear, pnMonth, pnDay,
 			       pnHour, pnMinute, pfSecond,
@@ -1472,10 +1477,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  void GetFieldAsIntegerList(const char* name, int *nLen, const int **pList) {
-      int id = OGR_F_GetFieldIndex(self, name);
+  void GetFieldAsIntegerList(const char* field_name, int *nLen, const int **pList) {
+      int id = OGR_F_GetFieldIndex(self, field_name);
       if (id == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           *pList = OGR_F_GetFieldAsIntegerList(self, id, nLen);
   }
@@ -1507,10 +1512,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  void GetFieldAsDoubleList(const char* name, int *nLen, const double **pList) {
-      int id = OGR_F_GetFieldIndex(self, name);
+  void GetFieldAsDoubleList(const char* field_name, int *nLen, const double **pList) {
+      int id = OGR_F_GetFieldIndex(self, field_name);
       if (id == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           *pList = OGR_F_GetFieldAsDoubleList(self, id, nLen);
   }
@@ -1535,10 +1540,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  void GetFieldAsStringList(const char* name, char ***pList) {
-      int id = OGR_F_GetFieldIndex(self, name);
+  void GetFieldAsStringList(const char* field_name, char ***pList) {
+      int id = OGR_F_GetFieldIndex(self, field_name);
       if (id == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           *pList = OGR_F_GetFieldAsStringList(self, id);
   }
@@ -1555,11 +1560,11 @@ public:
     return (GByte*)*pBuf;
   }
 
-  GByte* GetFieldAsBinary(const char* name, int *nLen, char **pBuf) {
-      int id = OGR_F_GetFieldIndex(self, name);
+  GByte* GetFieldAsBinary(const char* field_name, int *nLen, char **pBuf) {
+      int id = OGR_F_GetFieldIndex(self, field_name);
       if (id == -1)
       {
-        CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+        CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
         return NULL;
       }
       else
@@ -1580,11 +1585,11 @@ public:
   }
 
 #ifndef SWIGPERL
-  OGRErr GetFieldAsBinary(const char* name, int *nLen, char **pBuf) {
-      int id = OGR_F_GetFieldIndex(self, name);
+  OGRErr GetFieldAsBinary(const char* field_name, int *nLen, char **pBuf) {
+      int id = OGR_F_GetFieldIndex(self, field_name);
       if (id == -1)
       {
-        CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+        CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
         return OGRERR_FAILURE;
       }
       else
@@ -1606,10 +1611,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  bool IsFieldSet(const char* name) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  bool IsFieldSet(const char* field_name) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return (OGR_F_IsFieldSet(self, i) > 0);
       return false;
@@ -1623,10 +1628,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  bool IsFieldNull(const char* name) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  bool IsFieldNull(const char* field_name) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return (OGR_F_IsFieldNull(self, i) > 0);
       return false;
@@ -1640,10 +1645,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  bool IsFieldSetAndNotNull(const char* name) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  bool IsFieldSetAndNotNull(const char* field_name) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return (OGR_F_IsFieldSetAndNotNull(self, i) > 0);
       return false;
@@ -1651,14 +1656,14 @@ public:
 #endif
   /* ------------------------------------------- */
 
-  int GetFieldIndex(const char* name) {
+  int GetFieldIndex(const char* field_name) {
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_F_GetFieldIndex(self, name);
+      return OGR_F_GetFieldIndex(self, field_name);
   }
 
-  int GetGeomFieldIndex(const char* name) {
+  int GetGeomFieldIndex(const char* field_name) {
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_F_GetGeomFieldIndex(self, name);
+      return OGR_F_GetGeomFieldIndex(self, field_name);
   }
 
   GIntBig GetFID() {
@@ -1678,10 +1683,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  void UnsetField(const char* name) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  void UnsetField(const char* field_name) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           OGR_F_UnsetField(self, i);
   }
@@ -1692,10 +1697,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  void SetFieldNull(const char* name) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  void SetFieldNull(const char* field_name) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           OGR_F_SetFieldNull(self, i);
   }
@@ -1712,10 +1717,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  void SetField(const char* name, const char* value) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  void SetField(const char* field_name, const char* value) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           OGR_F_SetFieldString(self, i, value);
   }
@@ -1732,10 +1737,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  void SetField(const char* name, int value) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  void SetField(const char* field_name, int value) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  OGR_F_SetFieldInteger(self, i, value);
   }
@@ -1747,10 +1752,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  void SetField(const char* name, double value) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  void SetField(const char* field_name, double value) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  OGR_F_SetFieldDouble(self, i, value);
   }
@@ -1765,12 +1770,12 @@ public:
   }
 
 #ifndef SWIGPERL
-  void SetField(const char* name, int year, int month, int day,
+  void SetField(const char* field_name, int year, int month, int day,
                              int hour, int minute, float second,
                              int tzflag ) {
-      int i = OGR_F_GetFieldIndex(self, name);
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  OGR_F_SetFieldDateTimeEx(self, i, year, month, day,
 				 hour, minute, second,
@@ -1814,11 +1819,11 @@ public:
   }
 
 #ifndef SWIGPERL
-  void SetFieldBinaryFromHexString(const char* name, const char* pszValue)
+  void SetFieldBinaryFromHexString(const char* field_name, const char* pszValue)
   {
-      int i = OGR_F_GetFieldIndex(self, name);
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
       {
           int nBytes;
@@ -1870,10 +1875,10 @@ public:
   }
 
 #ifndef SWIGPERL
-  OGRFieldType GetFieldType(const char* name) {
-      int i = OGR_F_GetFieldIndex(self, name);
+  OGRFieldType GetFieldType(const char* field_name) {
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1) {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return (OGRFieldType)0;
       } else
           return (OGRFieldType) OGR_Fld_GetType( OGR_F_GetFieldDefnRef( self, i ) );
@@ -2032,9 +2037,9 @@ public:
     return (OGRFieldDefnShadow*) OGR_FD_GetFieldDefn(self, i);
   }
 
-  int GetFieldIndex(const char* name) {
+  int GetFieldIndex(const char* field_name) {
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_FD_GetFieldIndex(self, name);
+      return OGR_FD_GetFieldIndex(self, field_name);
   }
 
 %apply Pointer NONNULL {OGRFieldDefnShadow* defn};
@@ -2053,9 +2058,9 @@ public:
     return (OGRGeomFieldDefnShadow*) OGR_FD_GetGeomFieldDefn(self, i);
   }
 
-  int GetGeomFieldIndex(const char* name) {
+  int GetGeomFieldIndex(const char* field_name) {
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_FD_GetGeomFieldIndex(self, name);
+      return OGR_FD_GetGeomFieldIndex(self, field_name);
   }
 
 %apply Pointer NONNULL {OGRGeomFieldDefnShadow* defn};
@@ -3189,6 +3194,13 @@ public:
 }; /* class OGRGeometryShadow */
 
 
+
+#ifdef SWIGPYTHON
+/* Applies perhaps to other bindings */
+%clear (const char* field_name);
+#endif
+
+
 /************************************************************************/
 /*                        Other misc functions.                         */
 /************************************************************************/
diff --git a/swig/include/perl/typemaps_perl.i b/swig/include/perl/typemaps_perl.i
index ef3df43..03ed302 100644
--- a/swig/include/perl/typemaps_perl.i
+++ b/swig/include/perl/typemaps_perl.i
@@ -1561,6 +1561,17 @@ IF_UNDEF_NULL(const char *, target_key)
     if (tmpbuf$argnum) Safefree(tmpbuf$argnum);
 }
 
+%typemap(in, numinputs=1, fragment="sv_to_utf8_string") (const char* field_name) (U8 *tmpbuf = NULL)
+{
+    /* %typemap(in,numinputs=1) (const char* field_name) */
+    $1 = sv_to_utf8_string($input, &tmpbuf);
+}
+%typemap(freearg) (const char* field_name)
+{
+    /* %typemap(freearg) (const char* field_name) */
+    if (tmpbuf$argnum) Safefree(tmpbuf$argnum);
+}
+
 %typemap(in,numinputs=0) (int *pnBytes) (int bytes)
 {
     /* %typemap(in,numinputs=0) (int *pnBytes) (int bytes) */
diff --git a/swig/include/python/ogr_python.i b/swig/include/python/ogr_python.i
index a5d6244..002178f 100644
--- a/swig/include/python/ogr_python.i
+++ b/swig/include/python/ogr_python.i
@@ -1,5 +1,5 @@
 /*
- * $Id: ogr_python.i 37371 2017-02-13 11:41:59Z rouault $
+ * $Id: ogr_python.i 38101 2017-04-22 16:49:11Z rouault $
  *
  * python specific code for ogr bindings.
  */
@@ -286,7 +286,7 @@
             return self.SetField2( fld_index, value )
 
     def GetField(self, fld_index):
-        if isinstance(fld_index, str):
+        if isinstance(fld_index, str) or isinstance(fld_index, type(u'')):
             fld_index = self.GetFieldIndex(fld_index)
         if (fld_index < 0) or (fld_index > self.GetFieldCount()):
             raise ValueError("Illegal field requested in GetField()")
@@ -337,21 +337,21 @@
 
         if len(args) == 2 and (type(args[1]) == type(1) or type(args[1]) == type(12345678901234)):
             fld_index = args[0]
-            if isinstance(fld_index, str):
+            if isinstance(fld_index, str) or isinstance(fld_index, type(u'')):
                 fld_index = self.GetFieldIndex(fld_index)
             return _ogr.Feature_SetFieldInteger64(self, fld_index, args[1])
 
 
         if len(args) == 2 and str(type(args[1])) == "<type 'unicode'>":
             fld_index = args[0]
-            if isinstance(fld_index, str):
+            if isinstance(fld_index, str) or isinstance(fld_index, type(u'')):
                 fld_index = self.GetFieldIndex(fld_index)
             return _ogr.Feature_SetFieldString(self, fld_index, args[1])
 
         return _ogr.Feature_SetField(self, *args)
 
     def SetField2(self, fld_index, value):
-        if isinstance(fld_index, str):
+        if isinstance(fld_index, str) or isinstance(fld_index, type(u'')):
             fld_index = self.GetFieldIndex(fld_index)
         if (fld_index < 0) or (fld_index > self.GetFieldCount()):
             raise ValueError("Illegal field requested in SetField2()")
diff --git a/swig/java/javadoc.java b/swig/java/javadoc.java
index 601a2a2..bbe3ea1 100644
--- a/swig/java/javadoc.java
+++ b/swig/java/javadoc.java
@@ -1,5 +1,5 @@
 /* ***************************************************************************
-* $Id: javadoc.java 35425 2016-09-13 18:07:32Z rouault $
+* $Id: javadoc.java 38099 2017-04-22 16:40:28Z rouault $
 *
 * Project:  GDAL/OGR Java bindings
 * Purpose:  Documentation for the Java bindings
@@ -7648,10 +7648,10 @@ public class Feature:public long GetFID()
  * @param pnDay an allocated array of 1 integer to put the day (1-31)
  * @param pnHour an allocated array of 1 integer to put the hour (0-23)
  * @param pnMinute an allocated array of 1 integer to put the minute (0-59)
- * @param pnSecond an allocated array of 1 integer to put the second (0-59)
+ * @param pfSecond an allocated array of 1 integer to put the second (0-59)
  * @param pnTZFlag an allocated array of 1 integer to put the time zone flag (0=unknown, 1=localtime, 100=GMT, see data model for details)
  */
-public class Feature:public void GetFieldAsDateTime(int ifield, int[] pnYear, int[] pnMonth, int[] pnDay, int[] pnHour, int[] pnMinute, int[] pnSecond, int[] pnTZFlag)
+public class Feature:public void GetFieldAsDateTime(int ifield, int[] pnYear, int[] pnMonth, int[] pnDay, int[] pnHour, int[] pnMinute, float[] pfSecond, int[] pnTZFlag)
 
 /**
  * Fetch field value as a double.
@@ -7922,7 +7922,7 @@ public class Feature:public void SetField(int ifield, int val)
  * @param second (0-59)
  * @param tzflag (0=unknown, 1=localtime, 100=GMT, see data model for details)
  */
-public class Feature:public void SetField(int ifield, int year, int month, int day, int hour, int minute, int second, int tzflag)
+public class Feature:public void SetField(int ifield, int year, int month, int day, int hour, int minute, float second, int tzflag)
 
 /**
  * Set field to string value.
@@ -7977,7 +7977,7 @@ public class Feature:public void SetField(String name, int val)
  * @param second (0-59)
  * @param tzflag (0=unknown, 1=localtime, 100=GMT, see data model for details)
  */
-public class Feature:public void SetField(String name, int year, int month, int day, int hour, int minute, int second, int tzflag)
+public class Feature:public void SetField(String name, int year, int month, int day, int hour, int minute, float second, int tzflag)
 
 /**
  * Set field to string value.
diff --git a/swig/perl/ogr_wrap.cpp b/swig/perl/ogr_wrap.cpp
index d6caeb7..4d5783b 100644
--- a/swig/perl/ogr_wrap.cpp
+++ b/swig/perl/ogr_wrap.cpp
@@ -2233,11 +2233,11 @@ SWIGINTERN OGRGeometryShadow *OGRFeatureShadow_GetGeometryRef(OGRFeatureShadow *
 SWIGINTERN OGRErr OGRFeatureShadow_SetGeomField__SWIG_0(OGRFeatureShadow *self,int iField,OGRGeometryShadow *geom){
     return OGR_F_SetGeomField(self, iField, geom);
   }
-SWIGINTERN OGRErr OGRFeatureShadow_SetGeomField__SWIG_1(OGRFeatureShadow *self,char const *name,OGRGeometryShadow *geom){
-      int iField = OGR_F_GetGeomFieldIndex(self, name);
+SWIGINTERN OGRErr OGRFeatureShadow_SetGeomField__SWIG_1(OGRFeatureShadow *self,char const *field_name,OGRGeometryShadow *geom){
+      int iField = OGR_F_GetGeomFieldIndex(self, field_name);
       if (iField == -1)
       {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return OGRERR_FAILURE;
       }
       else
@@ -2246,11 +2246,11 @@ SWIGINTERN OGRErr OGRFeatureShadow_SetGeomField__SWIG_1(OGRFeatureShadow *self,c
 SWIGINTERN OGRErr OGRFeatureShadow_SetGeomFieldDirectly__SWIG_0(OGRFeatureShadow *self,int iField,OGRGeometryShadow *geom){
     return OGR_F_SetGeomFieldDirectly(self, iField, geom);
   }
-SWIGINTERN OGRErr OGRFeatureShadow_SetGeomFieldDirectly__SWIG_1(OGRFeatureShadow *self,char const *name,OGRGeometryShadow *geom){
-      int iField = OGR_F_GetGeomFieldIndex(self, name);
+SWIGINTERN OGRErr OGRFeatureShadow_SetGeomFieldDirectly__SWIG_1(OGRFeatureShadow *self,char const *field_name,OGRGeometryShadow *geom){
+      int iField = OGR_F_GetGeomFieldIndex(self, field_name);
       if (iField == -1)
       {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return OGRERR_FAILURE;
       }
       else
@@ -2259,11 +2259,11 @@ SWIGINTERN OGRErr OGRFeatureShadow_SetGeomFieldDirectly__SWIG_1(OGRFeatureShadow
 SWIGINTERN OGRGeometryShadow *OGRFeatureShadow_GetGeomFieldRef__SWIG_0(OGRFeatureShadow *self,int iField){
     return (OGRGeometryShadow*) OGR_F_GetGeomFieldRef(self, iField);
   }
-SWIGINTERN OGRGeometryShadow *OGRFeatureShadow_GetGeomFieldRef__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetGeomFieldIndex(self, name);
+SWIGINTERN OGRGeometryShadow *OGRFeatureShadow_GetGeomFieldRef__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetGeomFieldIndex(self, field_name);
       if (i == -1)
       {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return NULL;
       }
       else
@@ -2383,13 +2383,13 @@ SWIGINTERN bool OGRFeatureShadow_IsFieldNull(OGRFeatureShadow *self,int id){
 SWIGINTERN bool OGRFeatureShadow_IsFieldSetAndNotNull(OGRFeatureShadow *self,int id){
     return (OGR_F_IsFieldSetAndNotNull(self, id) > 0);
   }
-SWIGINTERN int OGRFeatureShadow_GetFieldIndex(OGRFeatureShadow *self,char const *name){
+SWIGINTERN int OGRFeatureShadow_GetFieldIndex(OGRFeatureShadow *self,char const *field_name){
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_F_GetFieldIndex(self, name);
+      return OGR_F_GetFieldIndex(self, field_name);
   }
-SWIGINTERN int OGRFeatureShadow_GetGeomFieldIndex(OGRFeatureShadow *self,char const *name){
+SWIGINTERN int OGRFeatureShadow_GetGeomFieldIndex(OGRFeatureShadow *self,char const *field_name){
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_F_GetGeomFieldIndex(self, name);
+      return OGR_F_GetGeomFieldIndex(self, field_name);
   }
 SWIGINTERN GIntBig OGRFeatureShadow_GetFID(OGRFeatureShadow *self){
     return OGR_F_GetFID(self);
@@ -2625,9 +2625,9 @@ SWIGINTERN int OGRFeatureDefnShadow_GetFieldCount(OGRFeatureDefnShadow *self){
 SWIGINTERN OGRFieldDefnShadow *OGRFeatureDefnShadow_GetFieldDefn(OGRFeatureDefnShadow *self,int i){
     return (OGRFieldDefnShadow*) OGR_FD_GetFieldDefn(self, i);
   }
-SWIGINTERN int OGRFeatureDefnShadow_GetFieldIndex(OGRFeatureDefnShadow *self,char const *name){
+SWIGINTERN int OGRFeatureDefnShadow_GetFieldIndex(OGRFeatureDefnShadow *self,char const *field_name){
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_FD_GetFieldIndex(self, name);
+      return OGR_FD_GetFieldIndex(self, field_name);
   }
 SWIGINTERN void OGRFeatureDefnShadow_AddFieldDefn(OGRFeatureDefnShadow *self,OGRFieldDefnShadow *defn){
     OGR_FD_AddFieldDefn(self, defn);
@@ -2638,9 +2638,9 @@ SWIGINTERN int OGRFeatureDefnShadow_GetGeomFieldCount(OGRFeatureDefnShadow *self
 SWIGINTERN OGRGeomFieldDefnShadow *OGRFeatureDefnShadow_GetGeomFieldDefn(OGRFeatureDefnShadow *self,int i){
     return (OGRGeomFieldDefnShadow*) OGR_FD_GetGeomFieldDefn(self, i);
   }
-SWIGINTERN int OGRFeatureDefnShadow_GetGeomFieldIndex(OGRFeatureDefnShadow *self,char const *name){
+SWIGINTERN int OGRFeatureDefnShadow_GetGeomFieldIndex(OGRFeatureDefnShadow *self,char const *field_name){
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_FD_GetGeomFieldIndex(self, name);
+      return OGR_FD_GetGeomFieldIndex(self, field_name);
   }
 SWIGINTERN void OGRFeatureDefnShadow_AddGeomFieldDefn(OGRFeatureDefnShadow *self,OGRGeomFieldDefnShadow *defn){
     OGR_FD_AddGeomFieldDefn(self, defn);
@@ -8203,7 +8203,7 @@ XS(_wrap_Feature_SetGeomField__SWIG_1) {
     dXSARGS;
     
     if ((items < 3) || (items > 3)) {
-      SWIG_croak("Usage: Feature_SetGeomField(self,name,geom);");
+      SWIG_croak("Usage: Feature_SetGeomField(self,field_name,geom);");
     }
     res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_OGRFeatureShadow, 0 |  0 );
     if (!SWIG_IsOK(res1)) {
@@ -8211,7 +8211,7 @@ XS(_wrap_Feature_SetGeomField__SWIG_1) {
     }
     arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
     {
-      /* %typemap(in,numinputs=1) (const char* name) */
+      /* %typemap(in,numinputs=1) (const char* field_name) */
       arg2 = sv_to_utf8_string(ST(1), &tmpbuf2);
     }
     res3 = SWIG_ConvertPtr(ST(2), &argp3,SWIGTYPE_p_OGRGeometryShadow, 0 |  0 );
@@ -8220,11 +8220,6 @@ XS(_wrap_Feature_SetGeomField__SWIG_1) {
     }
     arg3 = reinterpret_cast< OGRGeometryShadow * >(argp3);
     {
-      if (!arg2) {
-        SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-      }
-    }
-    {
       CPLErrorReset();
       result = (OGRErr)OGRFeatureShadow_SetGeomField__SWIG_1(arg1,(char const *)arg2,arg3);
       CPLErr eclass = CPLGetLastErrorType();
@@ -8258,7 +8253,7 @@ XS(_wrap_Feature_SetGeomField__SWIG_1) {
     }
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     
@@ -8266,7 +8261,7 @@ XS(_wrap_Feature_SetGeomField__SWIG_1) {
   fail:
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     
@@ -8463,7 +8458,7 @@ XS(_wrap_Feature_SetGeomFieldDirectly__SWIG_1) {
     dXSARGS;
     
     if ((items < 3) || (items > 3)) {
-      SWIG_croak("Usage: Feature_SetGeomFieldDirectly(self,name,geom);");
+      SWIG_croak("Usage: Feature_SetGeomFieldDirectly(self,field_name,geom);");
     }
     res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_OGRFeatureShadow, 0 |  0 );
     if (!SWIG_IsOK(res1)) {
@@ -8471,7 +8466,7 @@ XS(_wrap_Feature_SetGeomFieldDirectly__SWIG_1) {
     }
     arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
     {
-      /* %typemap(in,numinputs=1) (const char* name) */
+      /* %typemap(in,numinputs=1) (const char* field_name) */
       arg2 = sv_to_utf8_string(ST(1), &tmpbuf2);
     }
     res3 = SWIG_ConvertPtr(ST(2), SWIG_as_voidptrptr(&arg3), SWIGTYPE_p_OGRGeometryShadow, SWIG_POINTER_DISOWN |  0 );
@@ -8479,11 +8474,6 @@ XS(_wrap_Feature_SetGeomFieldDirectly__SWIG_1) {
       SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "Feature_SetGeomFieldDirectly" "', argument " "3"" of type '" "OGRGeometryShadow *""'");
     }
     {
-      if (!arg2) {
-        SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-      }
-    }
-    {
       CPLErrorReset();
       result = (OGRErr)OGRFeatureShadow_SetGeomFieldDirectly__SWIG_1(arg1,(char const *)arg2,arg3);
       CPLErr eclass = CPLGetLastErrorType();
@@ -8517,7 +8507,7 @@ XS(_wrap_Feature_SetGeomFieldDirectly__SWIG_1) {
     }
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     
@@ -8525,7 +8515,7 @@ XS(_wrap_Feature_SetGeomFieldDirectly__SWIG_1) {
   fail:
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     
@@ -8705,7 +8695,7 @@ XS(_wrap_Feature_GetGeomFieldRef__SWIG_1) {
     dXSARGS;
     
     if ((items < 2) || (items > 2)) {
-      SWIG_croak("Usage: Feature_GetGeomFieldRef(self,name);");
+      SWIG_croak("Usage: Feature_GetGeomFieldRef(self,field_name);");
     }
     res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_OGRFeatureShadow, 0 |  0 );
     if (!SWIG_IsOK(res1)) {
@@ -8713,15 +8703,10 @@ XS(_wrap_Feature_GetGeomFieldRef__SWIG_1) {
     }
     arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
     {
-      /* %typemap(in,numinputs=1) (const char* name) */
+      /* %typemap(in,numinputs=1) (const char* field_name) */
       arg2 = sv_to_utf8_string(ST(1), &tmpbuf2);
     }
     {
-      if (!arg2) {
-        SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-      }
-    }
-    {
       CPLErrorReset();
       result = (OGRGeometryShadow *)OGRFeatureShadow_GetGeomFieldRef__SWIG_1(arg1,(char const *)arg2);
       CPLErr eclass = CPLGetLastErrorType();
@@ -8748,14 +8733,14 @@ XS(_wrap_Feature_GetGeomFieldRef__SWIG_1) {
     ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OGRGeometryShadow, 0 | SWIG_SHADOW); argvi++ ;
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     XSRETURN(argvi);
   fail:
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     SWIG_croak_null();
@@ -10177,7 +10162,7 @@ XS(_wrap_Feature__GetFieldIndex) {
     dXSARGS;
     
     if ((items < 2) || (items > 2)) {
-      SWIG_croak("Usage: Feature__GetFieldIndex(self,name);");
+      SWIG_croak("Usage: Feature__GetFieldIndex(self,field_name);");
     }
     res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_OGRFeatureShadow, 0 |  0 );
     if (!SWIG_IsOK(res1)) {
@@ -10185,15 +10170,10 @@ XS(_wrap_Feature__GetFieldIndex) {
     }
     arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
     {
-      /* %typemap(in,numinputs=1) (const char* name) */
+      /* %typemap(in,numinputs=1) (const char* field_name) */
       arg2 = sv_to_utf8_string(ST(1), &tmpbuf2);
     }
     {
-      if (!arg2) {
-        SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-      }
-    }
-    {
       CPLErrorReset();
       result = (int)OGRFeatureShadow_GetFieldIndex(arg1,(char const *)arg2);
       CPLErr eclass = CPLGetLastErrorType();
@@ -10220,14 +10200,14 @@ XS(_wrap_Feature__GetFieldIndex) {
     ST(argvi) = SWIG_From_int  SWIG_PERL_CALL_ARGS_1(static_cast< int >(result)); argvi++ ;
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     XSRETURN(argvi);
   fail:
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     SWIG_croak_null();
@@ -10247,7 +10227,7 @@ XS(_wrap_Feature__GetGeomFieldIndex) {
     dXSARGS;
     
     if ((items < 2) || (items > 2)) {
-      SWIG_croak("Usage: Feature__GetGeomFieldIndex(self,name);");
+      SWIG_croak("Usage: Feature__GetGeomFieldIndex(self,field_name);");
     }
     res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_OGRFeatureShadow, 0 |  0 );
     if (!SWIG_IsOK(res1)) {
@@ -10255,15 +10235,10 @@ XS(_wrap_Feature__GetGeomFieldIndex) {
     }
     arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
     {
-      /* %typemap(in,numinputs=1) (const char* name) */
+      /* %typemap(in,numinputs=1) (const char* field_name) */
       arg2 = sv_to_utf8_string(ST(1), &tmpbuf2);
     }
     {
-      if (!arg2) {
-        SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-      }
-    }
-    {
       CPLErrorReset();
       result = (int)OGRFeatureShadow_GetGeomFieldIndex(arg1,(char const *)arg2);
       CPLErr eclass = CPLGetLastErrorType();
@@ -10290,14 +10265,14 @@ XS(_wrap_Feature__GetGeomFieldIndex) {
     ST(argvi) = SWIG_From_int  SWIG_PERL_CALL_ARGS_1(static_cast< int >(result)); argvi++ ;
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     XSRETURN(argvi);
   fail:
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     SWIG_croak_null();
@@ -12854,7 +12829,7 @@ XS(_wrap_FeatureDefn__GetFieldIndex) {
     dXSARGS;
     
     if ((items < 2) || (items > 2)) {
-      SWIG_croak("Usage: FeatureDefn__GetFieldIndex(self,name);");
+      SWIG_croak("Usage: FeatureDefn__GetFieldIndex(self,field_name);");
     }
     res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_OGRFeatureDefnShadow, 0 |  0 );
     if (!SWIG_IsOK(res1)) {
@@ -12862,15 +12837,10 @@ XS(_wrap_FeatureDefn__GetFieldIndex) {
     }
     arg1 = reinterpret_cast< OGRFeatureDefnShadow * >(argp1);
     {
-      /* %typemap(in,numinputs=1) (const char* name) */
+      /* %typemap(in,numinputs=1) (const char* field_name) */
       arg2 = sv_to_utf8_string(ST(1), &tmpbuf2);
     }
     {
-      if (!arg2) {
-        SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-      }
-    }
-    {
       CPLErrorReset();
       result = (int)OGRFeatureDefnShadow_GetFieldIndex(arg1,(char const *)arg2);
       CPLErr eclass = CPLGetLastErrorType();
@@ -12897,14 +12867,14 @@ XS(_wrap_FeatureDefn__GetFieldIndex) {
     ST(argvi) = SWIG_From_int  SWIG_PERL_CALL_ARGS_1(static_cast< int >(result)); argvi++ ;
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     XSRETURN(argvi);
   fail:
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     SWIG_croak_null();
@@ -13103,7 +13073,7 @@ XS(_wrap_FeatureDefn__GetGeomFieldIndex) {
     dXSARGS;
     
     if ((items < 2) || (items > 2)) {
-      SWIG_croak("Usage: FeatureDefn__GetGeomFieldIndex(self,name);");
+      SWIG_croak("Usage: FeatureDefn__GetGeomFieldIndex(self,field_name);");
     }
     res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_OGRFeatureDefnShadow, 0 |  0 );
     if (!SWIG_IsOK(res1)) {
@@ -13111,15 +13081,10 @@ XS(_wrap_FeatureDefn__GetGeomFieldIndex) {
     }
     arg1 = reinterpret_cast< OGRFeatureDefnShadow * >(argp1);
     {
-      /* %typemap(in,numinputs=1) (const char* name) */
+      /* %typemap(in,numinputs=1) (const char* field_name) */
       arg2 = sv_to_utf8_string(ST(1), &tmpbuf2);
     }
     {
-      if (!arg2) {
-        SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-      }
-    }
-    {
       CPLErrorReset();
       result = (int)OGRFeatureDefnShadow_GetGeomFieldIndex(arg1,(char const *)arg2);
       CPLErr eclass = CPLGetLastErrorType();
@@ -13146,14 +13111,14 @@ XS(_wrap_FeatureDefn__GetGeomFieldIndex) {
     ST(argvi) = SWIG_From_int  SWIG_PERL_CALL_ARGS_1(static_cast< int >(result)); argvi++ ;
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     XSRETURN(argvi);
   fail:
     
     {
-      /* %typemap(freearg) (const char* name) */
+      /* %typemap(freearg) (const char* field_name) */
       if (tmpbuf2) Safefree(tmpbuf2);
     }
     SWIG_croak_null();
diff --git a/swig/perl/t/ogr.t b/swig/perl/t/ogr.t
index 0b40b52..52f4465 100644
--- a/swig/perl/t/ogr.t
+++ b/swig/perl/t/ogr.t
@@ -85,7 +85,7 @@ use vars qw/%test_driver $loaded $verbose @types %pack_types @fails @tested_driv
     eval {
 	$g = Geo::OGR::Geometry->new(GeoJSON => "abc");
     };
-    ok ($@ =~ /GeoJSON parsing error/, "new from GeoJSON: $@");
+    ok ($@ =~ /JSON parsing error/, "new from GeoJSON: $@");
 }
 
 {
diff --git a/swig/python/extensions/ogr_wrap.cpp b/swig/python/extensions/ogr_wrap.cpp
index 0696dcb..e6aa07e 100644
--- a/swig/python/extensions/ogr_wrap.cpp
+++ b/swig/python/extensions/ogr_wrap.cpp
@@ -4101,11 +4101,11 @@ SWIGINTERN OGRGeometryShadow *OGRFeatureShadow_GetGeometryRef(OGRFeatureShadow *
 SWIGINTERN OGRErr OGRFeatureShadow_SetGeomField__SWIG_0(OGRFeatureShadow *self,int iField,OGRGeometryShadow *geom){
     return OGR_F_SetGeomField(self, iField, geom);
   }
-SWIGINTERN OGRErr OGRFeatureShadow_SetGeomField__SWIG_1(OGRFeatureShadow *self,char const *name,OGRGeometryShadow *geom){
-      int iField = OGR_F_GetGeomFieldIndex(self, name);
+SWIGINTERN OGRErr OGRFeatureShadow_SetGeomField__SWIG_1(OGRFeatureShadow *self,char const *field_name,OGRGeometryShadow *geom){
+      int iField = OGR_F_GetGeomFieldIndex(self, field_name);
       if (iField == -1)
       {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return 6;
       }
       else
@@ -4114,11 +4114,11 @@ SWIGINTERN OGRErr OGRFeatureShadow_SetGeomField__SWIG_1(OGRFeatureShadow *self,c
 SWIGINTERN OGRErr OGRFeatureShadow_SetGeomFieldDirectly__SWIG_0(OGRFeatureShadow *self,int iField,OGRGeometryShadow *geom){
     return OGR_F_SetGeomFieldDirectly(self, iField, geom);
   }
-SWIGINTERN OGRErr OGRFeatureShadow_SetGeomFieldDirectly__SWIG_1(OGRFeatureShadow *self,char const *name,OGRGeometryShadow *geom){
-      int iField = OGR_F_GetGeomFieldIndex(self, name);
+SWIGINTERN OGRErr OGRFeatureShadow_SetGeomFieldDirectly__SWIG_1(OGRFeatureShadow *self,char const *field_name,OGRGeometryShadow *geom){
+      int iField = OGR_F_GetGeomFieldIndex(self, field_name);
       if (iField == -1)
       {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return 6;
       }
       else
@@ -4127,11 +4127,11 @@ SWIGINTERN OGRErr OGRFeatureShadow_SetGeomFieldDirectly__SWIG_1(OGRFeatureShadow
 SWIGINTERN OGRGeometryShadow *OGRFeatureShadow_GetGeomFieldRef__SWIG_0(OGRFeatureShadow *self,int iField){
     return (OGRGeometryShadow*) OGR_F_GetGeomFieldRef(self, iField);
   }
-SWIGINTERN OGRGeometryShadow *OGRFeatureShadow_GetGeomFieldRef__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetGeomFieldIndex(self, name);
+SWIGINTERN OGRGeometryShadow *OGRFeatureShadow_GetGeomFieldRef__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetGeomFieldIndex(self, field_name);
       if (i == -1)
       {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return NULL;
       }
       else
@@ -4149,10 +4149,10 @@ SWIGINTERN int OGRFeatureShadow_GetFieldCount(OGRFeatureShadow *self){
 SWIGINTERN OGRFieldDefnShadow *OGRFeatureShadow_GetFieldDefnRef__SWIG_0(OGRFeatureShadow *self,int id){
     return (OGRFieldDefnShadow *) OGR_F_GetFieldDefnRef(self, id);
   }
-SWIGINTERN OGRFieldDefnShadow *OGRFeatureShadow_GetFieldDefnRef__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN OGRFieldDefnShadow *OGRFeatureShadow_GetFieldDefnRef__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           return (OGRFieldDefnShadow *) OGR_F_GetFieldDefnRef(self, i);
       return NULL;
@@ -4163,10 +4163,10 @@ SWIGINTERN int OGRFeatureShadow_GetGeomFieldCount(OGRFeatureShadow *self){
 SWIGINTERN OGRGeomFieldDefnShadow *OGRFeatureShadow_GetGeomFieldDefnRef__SWIG_0(OGRFeatureShadow *self,int id){
       return (OGRGeomFieldDefnShadow *) OGR_F_GetGeomFieldDefnRef(self, id);
   }
-SWIGINTERN OGRGeomFieldDefnShadow *OGRFeatureShadow_GetGeomFieldDefnRef__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetGeomFieldIndex(self, name);
+SWIGINTERN OGRGeomFieldDefnShadow *OGRFeatureShadow_GetGeomFieldDefnRef__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetGeomFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           return (OGRGeomFieldDefnShadow *) OGR_F_GetGeomFieldDefnRef(self, i);
       return NULL;
@@ -4174,10 +4174,10 @@ SWIGINTERN OGRGeomFieldDefnShadow *OGRFeatureShadow_GetGeomFieldDefnRef__SWIG_1(
 SWIGINTERN char const *OGRFeatureShadow_GetFieldAsString__SWIG_0(OGRFeatureShadow *self,int id){
     return (const char *) OGR_F_GetFieldAsString(self, id);
   }
-SWIGINTERN char const *OGRFeatureShadow_GetFieldAsString__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN char const *OGRFeatureShadow_GetFieldAsString__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return (const char *) OGR_F_GetFieldAsString(self, i);
       return NULL;
@@ -4185,10 +4185,10 @@ SWIGINTERN char const *OGRFeatureShadow_GetFieldAsString__SWIG_1(OGRFeatureShado
 SWIGINTERN int OGRFeatureShadow_GetFieldAsInteger__SWIG_0(OGRFeatureShadow *self,int id){
     return OGR_F_GetFieldAsInteger(self, id);
   }
-SWIGINTERN int OGRFeatureShadow_GetFieldAsInteger__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN int OGRFeatureShadow_GetFieldAsInteger__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return OGR_F_GetFieldAsInteger(self, i);
       return 0;
@@ -4196,10 +4196,10 @@ SWIGINTERN int OGRFeatureShadow_GetFieldAsInteger__SWIG_1(OGRFeatureShadow *self
 SWIGINTERN GIntBig OGRFeatureShadow_GetFieldAsInteger64__SWIG_0(OGRFeatureShadow *self,int id){
     return OGR_F_GetFieldAsInteger64(self, id);
   }
-SWIGINTERN GIntBig OGRFeatureShadow_GetFieldAsInteger64__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN GIntBig OGRFeatureShadow_GetFieldAsInteger64__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           return OGR_F_GetFieldAsInteger64(self, i);
       return 0;
@@ -4210,10 +4210,10 @@ SWIGINTERN double OGRFeatureShadow_GetFieldAsDouble__SWIG_0(OGRFeatureShadow *se
 
   #define SWIG_From_double   PyFloat_FromDouble 
 
-SWIGINTERN double OGRFeatureShadow_GetFieldAsDouble__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN double OGRFeatureShadow_GetFieldAsDouble__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           return OGR_F_GetFieldAsDouble(self, i);
       return 0;
@@ -4230,10 +4230,10 @@ SWIGINTERN void OGRFeatureShadow_GetFieldAsDateTime__SWIG_0(OGRFeatureShadow *se
 			       pnHour, pnMinute, pfSecond,
 			       pnTZFlag);
   }
-SWIGINTERN void OGRFeatureShadow_GetFieldAsDateTime__SWIG_1(OGRFeatureShadow *self,char const *name,int *pnYear,int *pnMonth,int *pnDay,int *pnHour,int *pnMinute,float *pfSecond,int *pnTZFlag){
-      int id = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_GetFieldAsDateTime__SWIG_1(OGRFeatureShadow *self,char const *field_name,int *pnYear,int *pnMonth,int *pnDay,int *pnHour,int *pnMinute,float *pfSecond,int *pnTZFlag){
+      int id = OGR_F_GetFieldIndex(self, field_name);
       if (id == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  OGR_F_GetFieldAsDateTimeEx(self, id, pnYear, pnMonth, pnDay,
 			       pnHour, pnMinute, pfSecond,
@@ -4242,10 +4242,10 @@ SWIGINTERN void OGRFeatureShadow_GetFieldAsDateTime__SWIG_1(OGRFeatureShadow *se
 SWIGINTERN void OGRFeatureShadow_GetFieldAsIntegerList__SWIG_0(OGRFeatureShadow *self,int id,int *nLen,int const **pList){
       *pList = OGR_F_GetFieldAsIntegerList(self, id, nLen);
   }
-SWIGINTERN void OGRFeatureShadow_GetFieldAsIntegerList__SWIG_1(OGRFeatureShadow *self,char const *name,int *nLen,int const **pList){
-      int id = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_GetFieldAsIntegerList__SWIG_1(OGRFeatureShadow *self,char const *field_name,int *nLen,int const **pList){
+      int id = OGR_F_GetFieldIndex(self, field_name);
       if (id == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           *pList = OGR_F_GetFieldAsIntegerList(self, id, nLen);
   }
@@ -4255,10 +4255,10 @@ SWIGINTERN void OGRFeatureShadow_GetFieldAsInteger64List(OGRFeatureShadow *self,
 SWIGINTERN void OGRFeatureShadow_GetFieldAsDoubleList__SWIG_0(OGRFeatureShadow *self,int id,int *nLen,double const **pList){
       *pList = OGR_F_GetFieldAsDoubleList(self, id, nLen);
   }
-SWIGINTERN void OGRFeatureShadow_GetFieldAsDoubleList__SWIG_1(OGRFeatureShadow *self,char const *name,int *nLen,double const **pList){
-      int id = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_GetFieldAsDoubleList__SWIG_1(OGRFeatureShadow *self,char const *field_name,int *nLen,double const **pList){
+      int id = OGR_F_GetFieldIndex(self, field_name);
       if (id == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           *pList = OGR_F_GetFieldAsDoubleList(self, id, nLen);
   }
@@ -4271,11 +4271,11 @@ SWIGINTERN OGRErr OGRFeatureShadow_GetFieldAsBinary__SWIG_0(OGRFeatureShadow *se
     memcpy(*pBuf, pabyBlob, *nLen);
     return 0;
   }
-SWIGINTERN OGRErr OGRFeatureShadow_GetFieldAsBinary__SWIG_1(OGRFeatureShadow *self,char const *name,int *nLen,char **pBuf){
-      int id = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN OGRErr OGRFeatureShadow_GetFieldAsBinary__SWIG_1(OGRFeatureShadow *self,char const *field_name,int *nLen,char **pBuf){
+      int id = OGR_F_GetFieldIndex(self, field_name);
       if (id == -1)
       {
-        CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+        CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
         return 6;
       }
       else
@@ -4289,10 +4289,10 @@ SWIGINTERN OGRErr OGRFeatureShadow_GetFieldAsBinary__SWIG_1(OGRFeatureShadow *se
 SWIGINTERN bool OGRFeatureShadow_IsFieldSet__SWIG_0(OGRFeatureShadow *self,int id){
     return (OGR_F_IsFieldSet(self, id) > 0);
   }
-SWIGINTERN bool OGRFeatureShadow_IsFieldSet__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN bool OGRFeatureShadow_IsFieldSet__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return (OGR_F_IsFieldSet(self, i) > 0);
       return false;
@@ -4300,10 +4300,10 @@ SWIGINTERN bool OGRFeatureShadow_IsFieldSet__SWIG_1(OGRFeatureShadow *self,char
 SWIGINTERN bool OGRFeatureShadow_IsFieldNull__SWIG_0(OGRFeatureShadow *self,int id){
     return (OGR_F_IsFieldNull(self, id) > 0);
   }
-SWIGINTERN bool OGRFeatureShadow_IsFieldNull__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN bool OGRFeatureShadow_IsFieldNull__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return (OGR_F_IsFieldNull(self, i) > 0);
       return false;
@@ -4311,21 +4311,21 @@ SWIGINTERN bool OGRFeatureShadow_IsFieldNull__SWIG_1(OGRFeatureShadow *self,char
 SWIGINTERN bool OGRFeatureShadow_IsFieldSetAndNotNull__SWIG_0(OGRFeatureShadow *self,int id){
     return (OGR_F_IsFieldSetAndNotNull(self, id) > 0);
   }
-SWIGINTERN bool OGRFeatureShadow_IsFieldSetAndNotNull__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN bool OGRFeatureShadow_IsFieldSetAndNotNull__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  return (OGR_F_IsFieldSetAndNotNull(self, i) > 0);
       return false;
   }
-SWIGINTERN int OGRFeatureShadow_GetFieldIndex(OGRFeatureShadow *self,char const *name){
+SWIGINTERN int OGRFeatureShadow_GetFieldIndex(OGRFeatureShadow *self,char const *field_name){
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_F_GetFieldIndex(self, name);
+      return OGR_F_GetFieldIndex(self, field_name);
   }
-SWIGINTERN int OGRFeatureShadow_GetGeomFieldIndex(OGRFeatureShadow *self,char const *name){
+SWIGINTERN int OGRFeatureShadow_GetGeomFieldIndex(OGRFeatureShadow *self,char const *field_name){
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_F_GetGeomFieldIndex(self, name);
+      return OGR_F_GetGeomFieldIndex(self, field_name);
   }
 SWIGINTERN GIntBig OGRFeatureShadow_GetFID(OGRFeatureShadow *self){
     return OGR_F_GetFID(self);
@@ -4339,30 +4339,30 @@ SWIGINTERN void OGRFeatureShadow_DumpReadable(OGRFeatureShadow *self){
 SWIGINTERN void OGRFeatureShadow_UnsetField__SWIG_0(OGRFeatureShadow *self,int id){
     OGR_F_UnsetField(self, id);
   }
-SWIGINTERN void OGRFeatureShadow_UnsetField__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_UnsetField__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           OGR_F_UnsetField(self, i);
   }
 SWIGINTERN void OGRFeatureShadow_SetFieldNull__SWIG_0(OGRFeatureShadow *self,int id){
     OGR_F_SetFieldNull(self, id);
   }
-SWIGINTERN void OGRFeatureShadow_SetFieldNull__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_SetFieldNull__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           OGR_F_SetFieldNull(self, i);
   }
 SWIGINTERN void OGRFeatureShadow_SetField__SWIG_0(OGRFeatureShadow *self,int id,char const *value){
     OGR_F_SetFieldString(self, id, value);
   }
-SWIGINTERN void OGRFeatureShadow_SetField__SWIG_1(OGRFeatureShadow *self,char const *name,char const *value){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_SetField__SWIG_1(OGRFeatureShadow *self,char const *field_name,char const *value){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
           OGR_F_SetFieldString(self, i, value);
   }
@@ -4372,10 +4372,10 @@ SWIGINTERN void OGRFeatureShadow_SetFieldInteger64(OGRFeatureShadow *self,int id
 SWIGINTERN void OGRFeatureShadow_SetField__SWIG_2(OGRFeatureShadow *self,int id,double value){
     OGR_F_SetFieldDouble(self, id, value);
   }
-SWIGINTERN void OGRFeatureShadow_SetField__SWIG_3(OGRFeatureShadow *self,char const *name,double value){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_SetField__SWIG_3(OGRFeatureShadow *self,char const *field_name,double value){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  OGR_F_SetFieldDouble(self, i, value);
   }
@@ -4421,10 +4421,10 @@ SWIGINTERN void OGRFeatureShadow_SetField__SWIG_4(OGRFeatureShadow *self,int id,
                              hour, minute, second,
                              tzflag);
   }
-SWIGINTERN void OGRFeatureShadow_SetField__SWIG_5(OGRFeatureShadow *self,char const *name,int year,int month,int day,int hour,int minute,float second,int tzflag){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_SetField__SWIG_5(OGRFeatureShadow *self,char const *field_name,int year,int month,int day,int hour,int minute,float second,int tzflag){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+	  CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
 	  OGR_F_SetFieldDateTimeEx(self, i, year, month, day,
 				 hour, minute, second,
@@ -4448,10 +4448,10 @@ SWIGINTERN void OGRFeatureShadow_SetFieldBinaryFromHexString__SWIG_0(OGRFeatureS
      OGR_F_SetFieldBinary(self, id, nBytes, pabyBuf);
      CPLFree(pabyBuf);
   }
-SWIGINTERN void OGRFeatureShadow_SetFieldBinaryFromHexString__SWIG_1(OGRFeatureShadow *self,char const *name,char const *pszValue){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN void OGRFeatureShadow_SetFieldBinaryFromHexString__SWIG_1(OGRFeatureShadow *self,char const *field_name,char const *pszValue){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1)
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
       else
       {
           int nBytes;
@@ -4485,10 +4485,10 @@ SWIGINTERN OGRFieldType OGRFeatureShadow_GetFieldType__SWIG_0(OGRFeatureShadow *
       else
           return (OGRFieldType)0;
   }
-SWIGINTERN OGRFieldType OGRFeatureShadow_GetFieldType__SWIG_1(OGRFeatureShadow *self,char const *name){
-      int i = OGR_F_GetFieldIndex(self, name);
+SWIGINTERN OGRFieldType OGRFeatureShadow_GetFieldType__SWIG_1(OGRFeatureShadow *self,char const *field_name){
+      int i = OGR_F_GetFieldIndex(self, field_name);
       if (i == -1) {
-          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, name);
+          CPLError(CE_Failure, 1, FIELD_NAME_ERROR_TMPL, field_name);
           return (OGRFieldType)0;
       } else
           return (OGRFieldType) OGR_Fld_GetType( OGR_F_GetFieldDefnRef( self, i ) );
@@ -4615,9 +4615,9 @@ SWIGINTERN int OGRFeatureDefnShadow_GetFieldCount(OGRFeatureDefnShadow *self){
 SWIGINTERN OGRFieldDefnShadow *OGRFeatureDefnShadow_GetFieldDefn(OGRFeatureDefnShadow *self,int i){
     return (OGRFieldDefnShadow*) OGR_FD_GetFieldDefn(self, i);
   }
-SWIGINTERN int OGRFeatureDefnShadow_GetFieldIndex(OGRFeatureDefnShadow *self,char const *name){
+SWIGINTERN int OGRFeatureDefnShadow_GetFieldIndex(OGRFeatureDefnShadow *self,char const *field_name){
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_FD_GetFieldIndex(self, name);
+      return OGR_FD_GetFieldIndex(self, field_name);
   }
 SWIGINTERN void OGRFeatureDefnShadow_AddFieldDefn(OGRFeatureDefnShadow *self,OGRFieldDefnShadow *defn){
     OGR_FD_AddFieldDefn(self, defn);
@@ -4628,9 +4628,9 @@ SWIGINTERN int OGRFeatureDefnShadow_GetGeomFieldCount(OGRFeatureDefnShadow *self
 SWIGINTERN OGRGeomFieldDefnShadow *OGRFeatureDefnShadow_GetGeomFieldDefn(OGRFeatureDefnShadow *self,int i){
     return (OGRGeomFieldDefnShadow*) OGR_FD_GetGeomFieldDefn(self, i);
   }
-SWIGINTERN int OGRFeatureDefnShadow_GetGeomFieldIndex(OGRFeatureDefnShadow *self,char const *name){
+SWIGINTERN int OGRFeatureDefnShadow_GetGeomFieldIndex(OGRFeatureDefnShadow *self,char const *field_name){
       // Do not issue an error if the field doesn't exist. It is intended to be silent
-      return OGR_FD_GetGeomFieldIndex(self, name);
+      return OGR_FD_GetGeomFieldIndex(self, field_name);
   }
 SWIGINTERN void OGRFeatureDefnShadow_AddGeomFieldDefn(OGRFeatureDefnShadow *self,OGRGeomFieldDefnShadow *defn){
     OGR_FD_AddGeomFieldDefn(self, defn);
@@ -14239,9 +14239,7 @@ SWIGINTERN PyObject *_wrap_Feature_SetGeomField__SWIG_1(PyObject *SWIGUNUSEDPARM
   OGRGeometryShadow *arg3 = (OGRGeometryShadow *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   void *argp3 = 0 ;
   int res3 = 0 ;
   PyObject * obj0 = 0 ;
@@ -14255,22 +14253,21 @@ SWIGINTERN PyObject *_wrap_Feature_SetGeomField__SWIG_1(PyObject *SWIGUNUSEDPARM
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_SetGeomField" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_SetGeomField" "', argument " "2"" of type '" "char const *""'");
+  {
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
+    }
   }
-  arg2 = reinterpret_cast< char * >(buf2);
   res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_OGRGeometryShadow, 0 |  0 );
   if (!SWIG_IsOK(res3)) {
     SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "Feature_SetGeomField" "', argument " "3"" of type '" "OGRGeometryShadow *""'"); 
   }
   arg3 = reinterpret_cast< OGRGeometryShadow * >(argp3);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-    }
-  }
-  {
     if ( bUseExceptions ) {
       CPLErrorReset();
     }
@@ -14299,7 +14296,10 @@ SWIGINTERN PyObject *_wrap_Feature_SetGeomField__SWIG_1(PyObject *SWIGUNUSEDPARM
       SWIG_fail;
     }
   }
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   {
     /* %typemap(ret) OGRErr */
     if ( ReturnSame(resultobj == Py_None || resultobj == 0) ) {
@@ -14309,7 +14309,10 @@ SWIGINTERN PyObject *_wrap_Feature_SetGeomField__SWIG_1(PyObject *SWIGUNUSEDPARM
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -14453,9 +14456,7 @@ SWIGINTERN PyObject *_wrap_Feature_SetGeomFieldDirectly__SWIG_1(PyObject *SWIGUN
   OGRGeometryShadow *arg3 = (OGRGeometryShadow *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
@@ -14468,21 +14469,20 @@ SWIGINTERN PyObject *_wrap_Feature_SetGeomFieldDirectly__SWIG_1(PyObject *SWIGUN
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_SetGeomFieldDirectly" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_SetGeomFieldDirectly" "', argument " "2"" of type '" "char const *""'");
+  {
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
+    }
   }
-  arg2 = reinterpret_cast< char * >(buf2);
   res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&arg3), SWIGTYPE_p_OGRGeometryShadow, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res3)) {
     SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "Feature_SetGeomFieldDirectly" "', argument " "3"" of type '" "OGRGeometryShadow *""'");
   }
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-    }
-  }
-  {
     if ( bUseExceptions ) {
       CPLErrorReset();
     }
@@ -14511,7 +14511,10 @@ SWIGINTERN PyObject *_wrap_Feature_SetGeomFieldDirectly__SWIG_1(PyObject *SWIGUN
       SWIG_fail;
     }
   }
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   {
     /* %typemap(ret) OGRErr */
     if ( ReturnSame(resultobj == Py_None || resultobj == 0) ) {
@@ -14521,7 +14524,10 @@ SWIGINTERN PyObject *_wrap_Feature_SetGeomFieldDirectly__SWIG_1(PyObject *SWIGUN
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -14641,9 +14647,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetGeomFieldRef__SWIG_1(PyObject *SWIGUNUSEDP
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   OGRGeometryShadow *result = 0 ;
@@ -14654,14 +14658,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetGeomFieldRef__SWIG_1(PyObject *SWIGUNUSEDP
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetGeomFieldRef" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetGeomFieldRef" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -14683,11 +14686,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetGeomFieldRef__SWIG_1(PyObject *SWIGUNUSEDP
 #endif
   }
   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OGRGeometryShadow, 0 |  0 );
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -14931,9 +14940,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldDefnRef__SWIG_1(PyObject *SWIGUNUSEDP
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   OGRFieldDefnShadow *result = 0 ;
@@ -14944,14 +14951,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldDefnRef__SWIG_1(PyObject *SWIGUNUSEDP
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetFieldDefnRef" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetFieldDefnRef" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -14973,11 +14979,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldDefnRef__SWIG_1(PyObject *SWIGUNUSEDP
 #endif
   }
   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OGRFieldDefnShadow, 0 |  0 );
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -15127,9 +15139,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetGeomFieldDefnRef__SWIG_1(PyObject *SWIGUNU
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   OGRGeomFieldDefnShadow *result = 0 ;
@@ -15140,14 +15150,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetGeomFieldDefnRef__SWIG_1(PyObject *SWIGUNU
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetGeomFieldDefnRef" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetGeomFieldDefnRef" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -15169,11 +15178,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetGeomFieldDefnRef__SWIG_1(PyObject *SWIGUNU
 #endif
   }
   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OGRGeomFieldDefnShadow, 0 |  0 );
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -15283,9 +15298,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsString__SWIG_1(PyObject *SWIGUNUSED
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   char *result = 0 ;
@@ -15296,14 +15309,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsString__SWIG_1(PyObject *SWIGUNUSED
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetFieldAsString" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetFieldAsString" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -15325,11 +15337,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsString__SWIG_1(PyObject *SWIGUNUSED
 #endif
   }
   resultobj = SWIG_FromCharPtr((const char *)result);
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -15439,9 +15457,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsInteger__SWIG_1(PyObject *SWIGUNUSE
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   int result;
@@ -15452,14 +15468,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsInteger__SWIG_1(PyObject *SWIGUNUSE
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetFieldAsInteger" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetFieldAsInteger" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -15481,11 +15496,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsInteger__SWIG_1(PyObject *SWIGUNUSE
 #endif
   }
   resultobj = SWIG_From_int(static_cast< int >(result));
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -15603,9 +15624,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsInteger64__SWIG_1(PyObject *SWIGUNU
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   GIntBig result;
@@ -15616,14 +15635,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsInteger64__SWIG_1(PyObject *SWIGUNU
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetFieldAsInteger64" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetFieldAsInteger64" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -15653,11 +15671,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsInteger64__SWIG_1(PyObject *SWIGUNU
     resultobj = PyInt_FromString(szTmp, NULL, 10);
 #endif
   }
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -15767,9 +15791,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsDouble__SWIG_1(PyObject *SWIGUNUSED
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   double result;
@@ -15780,14 +15802,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsDouble__SWIG_1(PyObject *SWIGUNUSED
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetFieldAsDouble" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetFieldAsDouble" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -15809,11 +15830,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsDouble__SWIG_1(PyObject *SWIGUNUSED
 #endif
   }
   resultobj = SWIG_From_double(static_cast< double >(result));
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -15999,9 +16026,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsDateTime__SWIG_1(PyObject *SWIGUNUS
   int *arg9 = (int *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   int temp3 ;
   int res3 = SWIG_TMPOBJ ;
   int temp4 ;
@@ -16032,14 +16057,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsDateTime__SWIG_1(PyObject *SWIGUNUS
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetFieldAsDateTime" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetFieldAsDateTime" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -16103,11 +16127,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsDateTime__SWIG_1(PyObject *SWIGUNUS
     int new_flags = SWIG_IsNewObj(res9) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
     resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg9), SWIGTYPE_p_int, new_flags));
   }
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -16237,9 +16267,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsIntegerList__SWIG_1(PyObject *SWIGU
   int **arg4 = (int **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   int nLen3 = 0 ;
   int *pList3 = NULL ;
   PyObject * obj0 = 0 ;
@@ -16256,14 +16284,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsIntegerList__SWIG_1(PyObject *SWIGU
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetFieldAsIntegerList" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetFieldAsIntegerList" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -16295,11 +16322,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsIntegerList__SWIG_1(PyObject *SWIGU
     }
     resultobj = out;
   }
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -16503,9 +16536,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsDoubleList__SWIG_1(PyObject *SWIGUN
   double **arg4 = (double **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   int nLen3 = 0 ;
   double *pList3 = NULL ;
   PyObject * obj0 = 0 ;
@@ -16522,14 +16553,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsDoubleList__SWIG_1(PyObject *SWIGUN
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetFieldAsDoubleList" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetFieldAsDoubleList" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -16561,11 +16591,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsDoubleList__SWIG_1(PyObject *SWIGUN
     }
     resultobj = out;
   }
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -16787,9 +16823,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsBinary__SWIG_1(PyObject *SWIGUNUSED
   char **arg4 = (char **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   int nLen3 = 0 ;
   char *pBuf3 = 0 ;
   PyObject * obj0 = 0 ;
@@ -16807,14 +16841,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsBinary__SWIG_1(PyObject *SWIGUNUSED
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetFieldAsBinary" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetFieldAsBinary" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -16855,7 +16888,10 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsBinary__SWIG_1(PyObject *SWIGUNUSED
     resultobj = PyString_FromStringAndSize( *arg4, *arg3 );
 #endif
   }
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   {
     /* %typemap(freearg) (int *nLen, char **pBuf ) */
     if( *arg3 ) {
@@ -16871,7 +16907,10 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldAsBinary__SWIG_1(PyObject *SWIGUNUSED
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   {
     /* %typemap(freearg) (int *nLen, char **pBuf ) */
     if( *arg3 ) {
@@ -16987,9 +17026,7 @@ SWIGINTERN PyObject *_wrap_Feature_IsFieldSet__SWIG_1(PyObject *SWIGUNUSEDPARM(s
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   bool result;
@@ -17000,14 +17037,13 @@ SWIGINTERN PyObject *_wrap_Feature_IsFieldSet__SWIG_1(PyObject *SWIGUNUSEDPARM(s
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_IsFieldSet" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_IsFieldSet" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -17029,11 +17065,17 @@ SWIGINTERN PyObject *_wrap_Feature_IsFieldSet__SWIG_1(PyObject *SWIGUNUSEDPARM(s
 #endif
   }
   resultobj = SWIG_From_bool(static_cast< bool >(result));
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -17143,9 +17185,7 @@ SWIGINTERN PyObject *_wrap_Feature_IsFieldNull__SWIG_1(PyObject *SWIGUNUSEDPARM(
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   bool result;
@@ -17156,14 +17196,13 @@ SWIGINTERN PyObject *_wrap_Feature_IsFieldNull__SWIG_1(PyObject *SWIGUNUSEDPARM(
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_IsFieldNull" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_IsFieldNull" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -17185,11 +17224,17 @@ SWIGINTERN PyObject *_wrap_Feature_IsFieldNull__SWIG_1(PyObject *SWIGUNUSEDPARM(
 #endif
   }
   resultobj = SWIG_From_bool(static_cast< bool >(result));
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -17299,9 +17344,7 @@ SWIGINTERN PyObject *_wrap_Feature_IsFieldSetAndNotNull__SWIG_1(PyObject *SWIGUN
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   bool result;
@@ -17312,14 +17355,13 @@ SWIGINTERN PyObject *_wrap_Feature_IsFieldSetAndNotNull__SWIG_1(PyObject *SWIGUN
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_IsFieldSetAndNotNull" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_IsFieldSetAndNotNull" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -17341,11 +17383,17 @@ SWIGINTERN PyObject *_wrap_Feature_IsFieldSetAndNotNull__SWIG_1(PyObject *SWIGUN
 #endif
   }
   resultobj = SWIG_From_bool(static_cast< bool >(result));
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -17406,9 +17454,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldIndex(PyObject *SWIGUNUSEDPARM(self),
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   int result;
@@ -17419,14 +17465,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldIndex(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetFieldIndex" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetFieldIndex" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -17448,11 +17493,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldIndex(PyObject *SWIGUNUSEDPARM(self),
 #endif
   }
   resultobj = SWIG_From_int(static_cast< int >(result));
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -17463,9 +17514,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetGeomFieldIndex(PyObject *SWIGUNUSEDPARM(se
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   int result;
@@ -17476,14 +17525,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetGeomFieldIndex(PyObject *SWIGUNUSEDPARM(se
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetGeomFieldIndex" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetGeomFieldIndex" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -17505,11 +17553,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetGeomFieldIndex(PyObject *SWIGUNUSEDPARM(se
 #endif
   }
   resultobj = SWIG_From_int(static_cast< int >(result));
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -17721,9 +17775,7 @@ SWIGINTERN PyObject *_wrap_Feature_UnsetField__SWIG_1(PyObject *SWIGUNUSEDPARM(s
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
@@ -17733,14 +17785,13 @@ SWIGINTERN PyObject *_wrap_Feature_UnsetField__SWIG_1(PyObject *SWIGUNUSEDPARM(s
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_UnsetField" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_UnsetField" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -17762,11 +17813,17 @@ SWIGINTERN PyObject *_wrap_Feature_UnsetField__SWIG_1(PyObject *SWIGUNUSEDPARM(s
 #endif
   }
   resultobj = SWIG_Py_Void();
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -17875,9 +17932,7 @@ SWIGINTERN PyObject *_wrap_Feature_SetFieldNull__SWIG_1(PyObject *SWIGUNUSEDPARM
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
@@ -17887,14 +17942,13 @@ SWIGINTERN PyObject *_wrap_Feature_SetFieldNull__SWIG_1(PyObject *SWIGUNUSEDPARM
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_SetFieldNull" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_SetFieldNull" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -17916,11 +17970,17 @@ SWIGINTERN PyObject *_wrap_Feature_SetFieldNull__SWIG_1(PyObject *SWIGUNUSEDPARM
 #endif
   }
   resultobj = SWIG_Py_Void();
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -18060,9 +18120,7 @@ SWIGINTERN PyObject *_wrap_Feature_SetField__SWIG_1(PyObject *SWIGUNUSEDPARM(sel
   char *arg3 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject *str3 = 0 ;
   int bToFree3 = 0 ;
   PyObject * obj0 = 0 ;
@@ -18075,11 +18133,15 @@ SWIGINTERN PyObject *_wrap_Feature_SetField__SWIG_1(PyObject *SWIGUNUSEDPARM(sel
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_SetField" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_SetField" "', argument " "2"" of type '" "char const *""'");
+  {
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
+    }
   }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
     /* %typemap(in) (tostring argin) */
     str3 = PyObject_Str( obj2 );
@@ -18091,11 +18153,6 @@ SWIGINTERN PyObject *_wrap_Feature_SetField__SWIG_1(PyObject *SWIGUNUSEDPARM(sel
     arg3 = GDALPythonObjectToCStr(str3, &bToFree3);
   }
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-    }
-  }
-  {
     if ( bUseExceptions ) {
       CPLErrorReset();
     }
@@ -18114,7 +18171,10 @@ SWIGINTERN PyObject *_wrap_Feature_SetField__SWIG_1(PyObject *SWIGUNUSEDPARM(sel
 #endif
   }
   resultobj = SWIG_Py_Void();
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   {
     /* %typemap(freearg) (tostring argin) */
     if ( str3 != NULL)
@@ -18126,7 +18186,10 @@ SWIGINTERN PyObject *_wrap_Feature_SetField__SWIG_1(PyObject *SWIGUNUSEDPARM(sel
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   {
     /* %typemap(freearg) (tostring argin) */
     if ( str3 != NULL)
@@ -18261,9 +18324,7 @@ SWIGINTERN PyObject *_wrap_Feature_SetField__SWIG_3(PyObject *SWIGUNUSEDPARM(sel
   double arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   double val3 ;
   int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
@@ -18276,22 +18337,21 @@ SWIGINTERN PyObject *_wrap_Feature_SetField__SWIG_3(PyObject *SWIGUNUSEDPARM(sel
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_SetField" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_SetField" "', argument " "2"" of type '" "char const *""'");
+  {
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
+    }
   }
-  arg2 = reinterpret_cast< char * >(buf2);
   ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
     SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Feature_SetField" "', argument " "3"" of type '" "double""'");
   } 
   arg3 = static_cast< double >(val3);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-    }
-  }
-  {
     if ( bUseExceptions ) {
       CPLErrorReset();
     }
@@ -18310,11 +18370,17 @@ SWIGINTERN PyObject *_wrap_Feature_SetField__SWIG_3(PyObject *SWIGUNUSEDPARM(sel
 #endif
   }
   resultobj = SWIG_Py_Void();
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -18443,9 +18509,7 @@ SWIGINTERN PyObject *_wrap_Feature_SetField__SWIG_5(PyObject *SWIGUNUSEDPARM(sel
   int arg9 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   int val3 ;
   int ecode3 = 0 ;
   int val4 ;
@@ -18476,11 +18540,15 @@ SWIGINTERN PyObject *_wrap_Feature_SetField__SWIG_5(PyObject *SWIGUNUSEDPARM(sel
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_SetField" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_SetField" "', argument " "2"" of type '" "char const *""'");
+  {
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
+    }
   }
-  arg2 = reinterpret_cast< char * >(buf2);
   ecode3 = SWIG_AsVal_int(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
     SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Feature_SetField" "', argument " "3"" of type '" "int""'");
@@ -18517,11 +18585,6 @@ SWIGINTERN PyObject *_wrap_Feature_SetField__SWIG_5(PyObject *SWIGUNUSEDPARM(sel
   } 
   arg9 = static_cast< int >(val9);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-    }
-  }
-  {
     if ( bUseExceptions ) {
       CPLErrorReset();
     }
@@ -18540,11 +18603,17 @@ SWIGINTERN PyObject *_wrap_Feature_SetField__SWIG_5(PyObject *SWIGUNUSEDPARM(sel
 #endif
   }
   resultobj = SWIG_Py_Void();
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -19199,9 +19268,7 @@ SWIGINTERN PyObject *_wrap_Feature_SetFieldBinaryFromHexString__SWIG_1(PyObject
   char *arg3 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   int res3 ;
   char *buf3 = 0 ;
   int alloc3 = 0 ;
@@ -19215,22 +19282,21 @@ SWIGINTERN PyObject *_wrap_Feature_SetFieldBinaryFromHexString__SWIG_1(PyObject
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_SetFieldBinaryFromHexString" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_SetFieldBinaryFromHexString" "', argument " "2"" of type '" "char const *""'");
+  {
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
+    }
   }
-  arg2 = reinterpret_cast< char * >(buf2);
   res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
   if (!SWIG_IsOK(res3)) {
     SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "Feature_SetFieldBinaryFromHexString" "', argument " "3"" of type '" "char const *""'");
   }
   arg3 = reinterpret_cast< char * >(buf3);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
-    }
-  }
-  {
     if ( bUseExceptions ) {
       CPLErrorReset();
     }
@@ -19249,12 +19315,18 @@ SWIGINTERN PyObject *_wrap_Feature_SetFieldBinaryFromHexString__SWIG_1(PyObject
 #endif
   }
   resultobj = SWIG_Py_Void();
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
   return NULL;
 }
@@ -19666,9 +19738,7 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldType__SWIG_1(PyObject *SWIGUNUSEDPARM
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   OGRFieldType result;
@@ -19679,14 +19749,13 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldType__SWIG_1(PyObject *SWIGUNUSEDPARM
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Feature_GetFieldType" "', argument " "1"" of type '" "OGRFeatureShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Feature_GetFieldType" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -19708,11 +19777,17 @@ SWIGINTERN PyObject *_wrap_Feature_GetFieldType__SWIG_1(PyObject *SWIGUNUSEDPARM
 #endif
   }
   resultobj = SWIG_From_int(static_cast< int >(result));
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -20414,9 +20489,7 @@ SWIGINTERN PyObject *_wrap_FeatureDefn_GetFieldIndex(PyObject *SWIGUNUSEDPARM(se
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   int result;
@@ -20427,14 +20500,13 @@ SWIGINTERN PyObject *_wrap_FeatureDefn_GetFieldIndex(PyObject *SWIGUNUSEDPARM(se
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FeatureDefn_GetFieldIndex" "', argument " "1"" of type '" "OGRFeatureDefnShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureDefnShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FeatureDefn_GetFieldIndex" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -20456,11 +20528,17 @@ SWIGINTERN PyObject *_wrap_FeatureDefn_GetFieldIndex(PyObject *SWIGUNUSEDPARM(se
 #endif
   }
   resultobj = SWIG_From_int(static_cast< int >(result));
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -20613,9 +20691,7 @@ SWIGINTERN PyObject *_wrap_FeatureDefn_GetGeomFieldIndex(PyObject *SWIGUNUSEDPAR
   char *arg2 = (char *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 ;
-  char *buf2 = 0 ;
-  int alloc2 = 0 ;
+  int bToFree2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   int result;
@@ -20626,14 +20702,13 @@ SWIGINTERN PyObject *_wrap_FeatureDefn_GetGeomFieldIndex(PyObject *SWIGUNUSEDPAR
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FeatureDefn_GetGeomFieldIndex" "', argument " "1"" of type '" "OGRFeatureDefnShadow *""'"); 
   }
   arg1 = reinterpret_cast< OGRFeatureDefnShadow * >(argp1);
-  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FeatureDefn_GetGeomFieldIndex" "', argument " "2"" of type '" "char const *""'");
-  }
-  arg2 = reinterpret_cast< char * >(buf2);
   {
-    if (!arg2) {
-      SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+    /* %typemap(in) (const char *utf8_path) */
+    arg2 = GDALPythonObjectToCStr( obj1, &bToFree2 );
+    if (arg2 == NULL)
+    {
+      PyErr_SetString( PyExc_RuntimeError, "not a string" );
+      SWIG_fail;
     }
   }
   {
@@ -20655,11 +20730,17 @@ SWIGINTERN PyObject *_wrap_FeatureDefn_GetGeomFieldIndex(PyObject *SWIGUNUSEDPAR
 #endif
   }
   resultobj = SWIG_From_int(static_cast< int >(result));
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   if ( ReturnSame(bLocalUseExceptionsCode) ) { CPLErr eclass = CPLGetLastErrorType(); if ( eclass == CE_Failure || eclass == CE_Fatal ) { Py_XDECREF(resultobj); SWIG_Error( SWIG_RuntimeError, CPLGetLastErrorMsg() ); return NULL; } }
   return resultobj;
 fail:
-  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  {
+    /* %typemap(freearg) (const char *utf8_path) */
+    GDALPythonFreeCStr(arg2, bToFree2);
+  }
   return NULL;
 }
 
@@ -32396,7 +32477,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_SetGeomField", _wrap_Feature_SetGeomField, METH_VARARGS, (char *)"\n"
 		"SetGeomField(int iField, Geometry geom) -> OGRErr\n"
-		"Feature_SetGeomField(Feature self, char const * name, Geometry geom) -> OGRErr\n"
+		"Feature_SetGeomField(Feature self, char const * field_name, Geometry geom) -> OGRErr\n"
 		"\n"
 		"OGRErr\n"
 		"OGR_F_SetGeomField(OGRFeatureH hFeat, int iField, OGRGeometryH hGeom)\n"
@@ -32424,7 +32505,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_SetGeomFieldDirectly", _wrap_Feature_SetGeomFieldDirectly, METH_VARARGS, (char *)"\n"
 		"SetGeomFieldDirectly(int iField, Geometry geom) -> OGRErr\n"
-		"Feature_SetGeomFieldDirectly(Feature self, char const * name, Geometry geom) -> OGRErr\n"
+		"Feature_SetGeomFieldDirectly(Feature self, char const * field_name, Geometry geom) -> OGRErr\n"
 		"\n"
 		"OGRErr\n"
 		"OGR_F_SetGeomFieldDirectly(OGRFeatureH hFeat, int iField, OGRGeometryH\n"
@@ -32456,7 +32537,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_GetGeomFieldRef", _wrap_Feature_GetGeomFieldRef, METH_VARARGS, (char *)"\n"
 		"GetGeomFieldRef(int iField) -> Geometry\n"
-		"Feature_GetGeomFieldRef(Feature self, char const * name) -> Geometry\n"
+		"Feature_GetGeomFieldRef(Feature self, char const * field_name) -> Geometry\n"
 		"\n"
 		"OGRGeometryH\n"
 		"OGR_F_GetGeomFieldRef(OGRFeatureH hFeat, int iField)\n"
@@ -32542,7 +32623,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_GetFieldDefnRef", _wrap_Feature_GetFieldDefnRef, METH_VARARGS, (char *)"\n"
 		"GetFieldDefnRef(int id) -> FieldDefn\n"
-		"Feature_GetFieldDefnRef(Feature self, char const * name) -> FieldDefn\n"
+		"Feature_GetFieldDefnRef(Feature self, char const * field_name) -> FieldDefn\n"
 		"\n"
 		"OGRFieldDefnH\n"
 		"OGR_F_GetFieldDefnRef(OGRFeatureH hFeat, int i)\n"
@@ -32585,7 +32666,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_GetGeomFieldDefnRef", _wrap_Feature_GetGeomFieldDefnRef, METH_VARARGS, (char *)"\n"
 		"GetGeomFieldDefnRef(int id) -> GeomFieldDefn\n"
-		"Feature_GetGeomFieldDefnRef(Feature self, char const * name) -> GeomFieldDefn\n"
+		"Feature_GetGeomFieldDefnRef(Feature self, char const * field_name) -> GeomFieldDefn\n"
 		"\n"
 		"OGRGeomFieldDefnH\n"
 		"OGR_F_GetGeomFieldDefnRef(OGRFeatureH hFeat, int i)\n"
@@ -32609,7 +32690,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_GetFieldAsString", _wrap_Feature_GetFieldAsString, METH_VARARGS, (char *)"\n"
 		"GetFieldAsString(int id) -> char const\n"
-		"Feature_GetFieldAsString(Feature self, char const * name) -> char const *\n"
+		"Feature_GetFieldAsString(Feature self, char const * field_name) -> char const *\n"
 		"\n"
 		"const char*\n"
 		"OGR_F_GetFieldAsString(OGRFeatureH hFeat, int iField)\n"
@@ -32635,7 +32716,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_GetFieldAsInteger", _wrap_Feature_GetFieldAsInteger, METH_VARARGS, (char *)"\n"
 		"GetFieldAsInteger(int id) -> int\n"
-		"Feature_GetFieldAsInteger(Feature self, char const * name) -> int\n"
+		"Feature_GetFieldAsInteger(Feature self, char const * field_name) -> int\n"
 		"\n"
 		"int\n"
 		"OGR_F_GetFieldAsInteger(OGRFeatureH hFeat, int iField)\n"
@@ -32660,7 +32741,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_GetFieldAsInteger64", _wrap_Feature_GetFieldAsInteger64, METH_VARARGS, (char *)"\n"
 		"GetFieldAsInteger64(int id) -> GIntBig\n"
-		"Feature_GetFieldAsInteger64(Feature self, char const * name) -> GIntBig\n"
+		"Feature_GetFieldAsInteger64(Feature self, char const * field_name) -> GIntBig\n"
 		"\n"
 		"GIntBig\n"
 		"OGR_F_GetFieldAsInteger64(OGRFeatureH hFeat, int iField)\n"
@@ -32688,7 +32769,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_GetFieldAsDouble", _wrap_Feature_GetFieldAsDouble, METH_VARARGS, (char *)"\n"
 		"GetFieldAsDouble(int id) -> double\n"
-		"Feature_GetFieldAsDouble(Feature self, char const * name) -> double\n"
+		"Feature_GetFieldAsDouble(Feature self, char const * field_name) -> double\n"
 		"\n"
 		"double\n"
 		"OGR_F_GetFieldAsDouble(OGRFeatureH hFeat, int iField)\n"
@@ -32713,7 +32794,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_GetFieldAsDateTime", _wrap_Feature_GetFieldAsDateTime, METH_VARARGS, (char *)"\n"
 		"GetFieldAsDateTime(int id)\n"
-		"Feature_GetFieldAsDateTime(Feature self, char const * name)\n"
+		"Feature_GetFieldAsDateTime(Feature self, char const * field_name)\n"
 		"\n"
 		"int\n"
 		"OGR_F_GetFieldAsDateTime(OGRFeatureH hFeat, int iField, int *pnYear,\n"
@@ -32757,7 +32838,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_GetFieldAsIntegerList", _wrap_Feature_GetFieldAsIntegerList, METH_VARARGS, (char *)"\n"
 		"GetFieldAsIntegerList(int id)\n"
-		"Feature_GetFieldAsIntegerList(Feature self, char const * name)\n"
+		"Feature_GetFieldAsIntegerList(Feature self, char const * field_name)\n"
 		"\n"
 		"const int*\n"
 		"OGR_F_GetFieldAsIntegerList(OGRFeatureH hFeat, int iField, int\n"
@@ -32814,7 +32895,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_GetFieldAsDoubleList", _wrap_Feature_GetFieldAsDoubleList, METH_VARARGS, (char *)"\n"
 		"GetFieldAsDoubleList(int id)\n"
-		"Feature_GetFieldAsDoubleList(Feature self, char const * name)\n"
+		"Feature_GetFieldAsDoubleList(Feature self, char const * field_name)\n"
 		"\n"
 		"const double*\n"
 		"OGR_F_GetFieldAsDoubleList(OGRFeatureH hFeat, int iField, int\n"
@@ -32868,7 +32949,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_GetFieldAsBinary", _wrap_Feature_GetFieldAsBinary, METH_VARARGS, (char *)"\n"
 		"GetFieldAsBinary(int id) -> OGRErr\n"
-		"Feature_GetFieldAsBinary(Feature self, char const * name) -> OGRErr\n"
+		"Feature_GetFieldAsBinary(Feature self, char const * field_name) -> OGRErr\n"
 		"\n"
 		"GByte*\n"
 		"OGR_F_GetFieldAsBinary(OGRFeatureH hFeat, int iField, int *pnBytes)\n"
@@ -32894,7 +32975,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_IsFieldSet", _wrap_Feature_IsFieldSet, METH_VARARGS, (char *)"\n"
 		"IsFieldSet(int id) -> bool\n"
-		"Feature_IsFieldSet(Feature self, char const * name) -> bool\n"
+		"Feature_IsFieldSet(Feature self, char const * field_name) -> bool\n"
 		"\n"
 		"int OGR_F_IsFieldSet(OGRFeatureH\n"
 		"hFeat, int iField)\n"
@@ -32914,14 +32995,14 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_IsFieldNull", _wrap_Feature_IsFieldNull, METH_VARARGS, (char *)"\n"
 		"IsFieldNull(int id) -> bool\n"
-		"Feature_IsFieldNull(Feature self, char const * name) -> bool\n"
+		"Feature_IsFieldNull(Feature self, char const * field_name) -> bool\n"
 		""},
 	 { (char *)"Feature_IsFieldSetAndNotNull", _wrap_Feature_IsFieldSetAndNotNull, METH_VARARGS, (char *)"\n"
 		"IsFieldSetAndNotNull(int id) -> bool\n"
-		"Feature_IsFieldSetAndNotNull(Feature self, char const * name) -> bool\n"
+		"Feature_IsFieldSetAndNotNull(Feature self, char const * field_name) -> bool\n"
 		""},
 	 { (char *)"Feature_GetFieldIndex", _wrap_Feature_GetFieldIndex, METH_VARARGS, (char *)"\n"
-		"Feature_GetFieldIndex(Feature self, char const * name) -> int\n"
+		"Feature_GetFieldIndex(Feature self, char const * field_name) -> int\n"
 		"\n"
 		"int\n"
 		"OGR_F_GetFieldIndex(OGRFeatureH hFeat, const char *pszName)\n"
@@ -32943,7 +33024,7 @@ static PyMethodDef SwigMethods[] = {
 		"the field index, or -1 if no matching field is found. \n"
 		""},
 	 { (char *)"Feature_GetGeomFieldIndex", _wrap_Feature_GetGeomFieldIndex, METH_VARARGS, (char *)"\n"
-		"Feature_GetGeomFieldIndex(Feature self, char const * name) -> int\n"
+		"Feature_GetGeomFieldIndex(Feature self, char const * field_name) -> int\n"
 		"\n"
 		"int\n"
 		"OGR_F_GetGeomFieldIndex(OGRFeatureH hFeat, const char *pszName)\n"
@@ -33035,7 +33116,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_UnsetField", _wrap_Feature_UnsetField, METH_VARARGS, (char *)"\n"
 		"UnsetField(int id)\n"
-		"Feature_UnsetField(Feature self, char const * name)\n"
+		"Feature_UnsetField(Feature self, char const * field_name)\n"
 		"\n"
 		"void OGR_F_UnsetField(OGRFeatureH\n"
 		"hFeat, int iField)\n"
@@ -33053,7 +33134,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_SetFieldNull", _wrap_Feature_SetFieldNull, METH_VARARGS, (char *)"\n"
 		"SetFieldNull(int id)\n"
-		"Feature_SetFieldNull(Feature self, char const * name)\n"
+		"Feature_SetFieldNull(Feature self, char const * field_name)\n"
 		""},
 	 { (char *)"Feature_SetFieldInteger64", _wrap_Feature_SetFieldInteger64, METH_VARARGS, (char *)"\n"
 		"Feature_SetFieldInteger64(Feature self, int id, GIntBig value)\n"
@@ -33083,11 +33164,11 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_SetField", _wrap_Feature_SetField, METH_VARARGS, (char *)"\n"
 		"SetField(int id, char const * value)\n"
-		"SetField(char const * name, char const * value)\n"
+		"SetField(char const * field_name, char const * value)\n"
 		"SetField(int id, double value)\n"
-		"SetField(char const * name, double value)\n"
+		"SetField(char const * field_name, double value)\n"
 		"SetField(int id, int year, int month, int day, int hour, int minute, float second, int tzflag)\n"
-		"Feature_SetField(Feature self, char const * name, int year, int month, int day, int hour, int minute, float second, int tzflag)\n"
+		"Feature_SetField(Feature self, char const * field_name, int year, int month, int day, int hour, int minute, float second, int tzflag)\n"
 		""},
 	 { (char *)"Feature_SetFieldIntegerList", _wrap_Feature_SetFieldIntegerList, METH_VARARGS, (char *)"\n"
 		"Feature_SetFieldIntegerList(Feature self, int id, int nList)\n"
@@ -33190,7 +33271,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_SetFieldBinaryFromHexString", _wrap_Feature_SetFieldBinaryFromHexString, METH_VARARGS, (char *)"\n"
 		"SetFieldBinaryFromHexString(int id, char const * pszValue)\n"
-		"Feature_SetFieldBinaryFromHexString(Feature self, char const * name, char const * pszValue)\n"
+		"Feature_SetFieldBinaryFromHexString(Feature self, char const * field_name, char const * pszValue)\n"
 		""},
 	 { (char *)"Feature_SetFrom", (PyCFunction) _wrap_Feature_SetFrom, METH_VARARGS | METH_KEYWORDS, (char *)"\n"
 		"Feature_SetFrom(Feature self, Feature other, int forgiving=1) -> OGRErr\n"
@@ -33310,7 +33391,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"Feature_GetFieldType", _wrap_Feature_GetFieldType, METH_VARARGS, (char *)"\n"
 		"GetFieldType(int id) -> OGRFieldType\n"
-		"Feature_GetFieldType(Feature self, char const * name) -> OGRFieldType\n"
+		"Feature_GetFieldType(Feature self, char const * field_name) -> OGRFieldType\n"
 		""},
 	 { (char *)"Feature_Validate", _wrap_Feature_Validate, METH_VARARGS, (char *)"\n"
 		"Feature_Validate(Feature self, int flags, int bEmitError=True) -> int\n"
@@ -33589,7 +33670,7 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"FeatureDefn_GetFieldIndex", _wrap_FeatureDefn_GetFieldIndex, METH_VARARGS, (char *)"\n"
-		"FeatureDefn_GetFieldIndex(FeatureDefn self, char const * name) -> int\n"
+		"FeatureDefn_GetFieldIndex(FeatureDefn self, char const * field_name) -> int\n"
 		"\n"
 		"int\n"
 		"OGR_FD_GetFieldIndex(OGRFeatureDefnH hDefn, const char *pszFieldName)\n"
@@ -33683,7 +33764,7 @@ static PyMethodDef SwigMethods[] = {
 		"GDAL 1.11 \n"
 		""},
 	 { (char *)"FeatureDefn_GetGeomFieldIndex", _wrap_FeatureDefn_GetGeomFieldIndex, METH_VARARGS, (char *)"\n"
-		"FeatureDefn_GetGeomFieldIndex(FeatureDefn self, char const * name) -> int\n"
+		"FeatureDefn_GetGeomFieldIndex(FeatureDefn self, char const * field_name) -> int\n"
 		"\n"
 		"int\n"
 		"OGR_FD_GetGeomFieldIndex(OGRFeatureDefnH hDefn, const char\n"
diff --git a/swig/python/osgeo/ogr.py b/swig/python/osgeo/ogr.py
index eb2fa7e..2e5904e 100644
--- a/swig/python/osgeo/ogr.py
+++ b/swig/python/osgeo/ogr.py
@@ -3341,7 +3341,7 @@ class Feature(_object):
     def SetGeomField(self, *args):
         """
         SetGeomField(Feature self, int iField, Geometry geom) -> OGRErr
-        SetGeomField(Feature self, char const * name, Geometry geom) -> OGRErr
+        SetGeomField(Feature self, char const * field_name, Geometry geom) -> OGRErr
 
         OGRErr
         OGR_F_SetGeomField(OGRFeatureH hFeat, int iField, OGRGeometryH hGeom)
@@ -3373,7 +3373,7 @@ class Feature(_object):
     def SetGeomFieldDirectly(self, *args):
         """
         SetGeomFieldDirectly(Feature self, int iField, Geometry geom) -> OGRErr
-        SetGeomFieldDirectly(Feature self, char const * name, Geometry geom) -> OGRErr
+        SetGeomFieldDirectly(Feature self, char const * field_name, Geometry geom) -> OGRErr
 
         OGRErr
         OGR_F_SetGeomFieldDirectly(OGRFeatureH hFeat, int iField, OGRGeometryH
@@ -3409,7 +3409,7 @@ class Feature(_object):
     def GetGeomFieldRef(self, *args):
         """
         GetGeomFieldRef(Feature self, int iField) -> Geometry
-        GetGeomFieldRef(Feature self, char const * name) -> Geometry
+        GetGeomFieldRef(Feature self, char const * field_name) -> Geometry
 
         OGRGeometryH
         OGR_F_GetGeomFieldRef(OGRFeatureH hFeat, int iField)
@@ -3511,7 +3511,7 @@ class Feature(_object):
     def GetFieldDefnRef(self, *args):
         """
         GetFieldDefnRef(Feature self, int id) -> FieldDefn
-        GetFieldDefnRef(Feature self, char const * name) -> FieldDefn
+        GetFieldDefnRef(Feature self, char const * field_name) -> FieldDefn
 
         OGRFieldDefnH
         OGR_F_GetFieldDefnRef(OGRFeatureH hFeat, int i)
@@ -3562,7 +3562,7 @@ class Feature(_object):
     def GetGeomFieldDefnRef(self, *args):
         """
         GetGeomFieldDefnRef(Feature self, int id) -> GeomFieldDefn
-        GetGeomFieldDefnRef(Feature self, char const * name) -> GeomFieldDefn
+        GetGeomFieldDefnRef(Feature self, char const * field_name) -> GeomFieldDefn
 
         OGRGeomFieldDefnH
         OGR_F_GetGeomFieldDefnRef(OGRFeatureH hFeat, int i)
@@ -3590,7 +3590,7 @@ class Feature(_object):
     def GetFieldAsString(self, *args):
         """
         GetFieldAsString(Feature self, int id) -> char const
-        GetFieldAsString(Feature self, char const * name) -> char const *
+        GetFieldAsString(Feature self, char const * field_name) -> char const *
 
         const char*
         OGR_F_GetFieldAsString(OGRFeatureH hFeat, int iField)
@@ -3620,7 +3620,7 @@ class Feature(_object):
     def GetFieldAsInteger(self, *args):
         """
         GetFieldAsInteger(Feature self, int id) -> int
-        GetFieldAsInteger(Feature self, char const * name) -> int
+        GetFieldAsInteger(Feature self, char const * field_name) -> int
 
         int
         OGR_F_GetFieldAsInteger(OGRFeatureH hFeat, int iField)
@@ -3649,7 +3649,7 @@ class Feature(_object):
     def GetFieldAsInteger64(self, *args):
         """
         GetFieldAsInteger64(Feature self, int id) -> GIntBig
-        GetFieldAsInteger64(Feature self, char const * name) -> GIntBig
+        GetFieldAsInteger64(Feature self, char const * field_name) -> GIntBig
 
         GIntBig
         OGR_F_GetFieldAsInteger64(OGRFeatureH hFeat, int iField)
@@ -3681,7 +3681,7 @@ class Feature(_object):
     def GetFieldAsDouble(self, *args):
         """
         GetFieldAsDouble(Feature self, int id) -> double
-        GetFieldAsDouble(Feature self, char const * name) -> double
+        GetFieldAsDouble(Feature self, char const * field_name) -> double
 
         double
         OGR_F_GetFieldAsDouble(OGRFeatureH hFeat, int iField)
@@ -3710,7 +3710,7 @@ class Feature(_object):
     def GetFieldAsDateTime(self, *args):
         """
         GetFieldAsDateTime(Feature self, int id)
-        GetFieldAsDateTime(Feature self, char const * name)
+        GetFieldAsDateTime(Feature self, char const * field_name)
 
         int
         OGR_F_GetFieldAsDateTime(OGRFeatureH hFeat, int iField, int *pnYear,
@@ -3758,7 +3758,7 @@ class Feature(_object):
     def GetFieldAsIntegerList(self, *args):
         """
         GetFieldAsIntegerList(Feature self, int id)
-        GetFieldAsIntegerList(Feature self, char const * name)
+        GetFieldAsIntegerList(Feature self, char const * field_name)
 
         const int*
         OGR_F_GetFieldAsIntegerList(OGRFeatureH hFeat, int iField, int
@@ -3823,7 +3823,7 @@ class Feature(_object):
     def GetFieldAsDoubleList(self, *args):
         """
         GetFieldAsDoubleList(Feature self, int id)
-        GetFieldAsDoubleList(Feature self, char const * name)
+        GetFieldAsDoubleList(Feature self, char const * field_name)
 
         const double*
         OGR_F_GetFieldAsDoubleList(OGRFeatureH hFeat, int iField, int
@@ -3885,7 +3885,7 @@ class Feature(_object):
     def GetFieldAsBinary(self, *args):
         """
         GetFieldAsBinary(Feature self, int id) -> OGRErr
-        GetFieldAsBinary(Feature self, char const * name) -> OGRErr
+        GetFieldAsBinary(Feature self, char const * field_name) -> OGRErr
 
         GByte*
         OGR_F_GetFieldAsBinary(OGRFeatureH hFeat, int iField, int *pnBytes)
@@ -3915,7 +3915,7 @@ class Feature(_object):
     def IsFieldSet(self, *args):
         """
         IsFieldSet(Feature self, int id) -> bool
-        IsFieldSet(Feature self, char const * name) -> bool
+        IsFieldSet(Feature self, char const * field_name) -> bool
 
         int OGR_F_IsFieldSet(OGRFeatureH
         hFeat, int iField)
@@ -3939,7 +3939,7 @@ class Feature(_object):
     def IsFieldNull(self, *args):
         """
         IsFieldNull(Feature self, int id) -> bool
-        IsFieldNull(Feature self, char const * name) -> bool
+        IsFieldNull(Feature self, char const * field_name) -> bool
         """
         return _ogr.Feature_IsFieldNull(self, *args)
 
@@ -3947,14 +3947,14 @@ class Feature(_object):
     def IsFieldSetAndNotNull(self, *args):
         """
         IsFieldSetAndNotNull(Feature self, int id) -> bool
-        IsFieldSetAndNotNull(Feature self, char const * name) -> bool
+        IsFieldSetAndNotNull(Feature self, char const * field_name) -> bool
         """
         return _ogr.Feature_IsFieldSetAndNotNull(self, *args)
 
 
     def GetFieldIndex(self, *args):
         """
-        GetFieldIndex(Feature self, char const * name) -> int
+        GetFieldIndex(Feature self, char const * field_name) -> int
 
         int
         OGR_F_GetFieldIndex(OGRFeatureH hFeat, const char *pszName)
@@ -3980,7 +3980,7 @@ class Feature(_object):
 
     def GetGeomFieldIndex(self, *args):
         """
-        GetGeomFieldIndex(Feature self, char const * name) -> int
+        GetGeomFieldIndex(Feature self, char const * field_name) -> int
 
         int
         OGR_F_GetGeomFieldIndex(OGRFeatureH hFeat, const char *pszName)
@@ -4088,7 +4088,7 @@ class Feature(_object):
     def UnsetField(self, *args):
         """
         UnsetField(Feature self, int id)
-        UnsetField(Feature self, char const * name)
+        UnsetField(Feature self, char const * field_name)
 
         void OGR_F_UnsetField(OGRFeatureH
         hFeat, int iField)
@@ -4110,7 +4110,7 @@ class Feature(_object):
     def SetFieldNull(self, *args):
         """
         SetFieldNull(Feature self, int id)
-        SetFieldNull(Feature self, char const * name)
+        SetFieldNull(Feature self, char const * field_name)
         """
         return _ogr.Feature_SetFieldNull(self, *args)
 
@@ -4148,11 +4148,11 @@ class Feature(_object):
     def SetField(self, *args):
         """
         SetField(Feature self, int id, char const * value)
-        SetField(Feature self, char const * name, char const * value)
+        SetField(Feature self, char const * field_name, char const * value)
         SetField(Feature self, int id, double value)
-        SetField(Feature self, char const * name, double value)
+        SetField(Feature self, char const * field_name, double value)
         SetField(Feature self, int id, int year, int month, int day, int hour, int minute, float second, int tzflag)
-        SetField(Feature self, char const * name, int year, int month, int day, int hour, int minute, float second, int tzflag)
+        SetField(Feature self, char const * field_name, int year, int month, int day, int hour, int minute, float second, int tzflag)
         """
         return _ogr.Feature_SetField(self, *args)
 
@@ -4275,7 +4275,7 @@ class Feature(_object):
     def SetFieldBinaryFromHexString(self, *args):
         """
         SetFieldBinaryFromHexString(Feature self, int id, char const * pszValue)
-        SetFieldBinaryFromHexString(Feature self, char const * name, char const * pszValue)
+        SetFieldBinaryFromHexString(Feature self, char const * field_name, char const * pszValue)
         """
         return _ogr.Feature_SetFieldBinaryFromHexString(self, *args)
 
@@ -4415,7 +4415,7 @@ class Feature(_object):
     def GetFieldType(self, *args):
         """
         GetFieldType(Feature self, int id) -> OGRFieldType
-        GetFieldType(Feature self, char const * name) -> OGRFieldType
+        GetFieldType(Feature self, char const * field_name) -> OGRFieldType
         """
         return _ogr.Feature_GetFieldType(self, *args)
 
@@ -4743,7 +4743,7 @@ class Feature(_object):
             return self.SetField2( fld_index, value )
 
     def GetField(self, fld_index):
-        if isinstance(fld_index, str):
+        if isinstance(fld_index, str) or isinstance(fld_index, type(u'')):
             fld_index = self.GetFieldIndex(fld_index)
         if (fld_index < 0) or (fld_index > self.GetFieldCount()):
             raise ValueError("Illegal field requested in GetField()")
@@ -4794,21 +4794,21 @@ class Feature(_object):
 
         if len(args) == 2 and (type(args[1]) == type(1) or type(args[1]) == type(12345678901234)):
             fld_index = args[0]
-            if isinstance(fld_index, str):
+            if isinstance(fld_index, str) or isinstance(fld_index, type(u'')):
                 fld_index = self.GetFieldIndex(fld_index)
             return _ogr.Feature_SetFieldInteger64(self, fld_index, args[1])
 
 
         if len(args) == 2 and str(type(args[1])) == "<type 'unicode'>":
             fld_index = args[0]
-            if isinstance(fld_index, str):
+            if isinstance(fld_index, str) or isinstance(fld_index, type(u'')):
                 fld_index = self.GetFieldIndex(fld_index)
             return _ogr.Feature_SetFieldString(self, fld_index, args[1])
 
         return _ogr.Feature_SetField(self, *args)
 
     def SetField2(self, fld_index, value):
-        if isinstance(fld_index, str):
+        if isinstance(fld_index, str) or isinstance(fld_index, type(u'')):
             fld_index = self.GetFieldIndex(fld_index)
         if (fld_index < 0) or (fld_index > self.GetFieldCount()):
             raise ValueError("Illegal field requested in SetField2()")
@@ -5001,7 +5001,7 @@ class FeatureDefn(_object):
 
     def GetFieldIndex(self, *args):
         """
-        GetFieldIndex(FeatureDefn self, char const * name) -> int
+        GetFieldIndex(FeatureDefn self, char const * field_name) -> int
 
         int
         OGR_FD_GetFieldIndex(OGRFeatureDefnH hDefn, const char *pszFieldName)
@@ -5111,7 +5111,7 @@ class FeatureDefn(_object):
 
     def GetGeomFieldIndex(self, *args):
         """
-        GetGeomFieldIndex(FeatureDefn self, char const * name) -> int
+        GetGeomFieldIndex(FeatureDefn self, char const * field_name) -> int
 
         int
         OGR_FD_GetGeomFieldIndex(OGRFeatureDefnH hDefn, const char
diff --git a/swig/python/samples/validate_gpkg.py b/swig/python/samples/validate_gpkg.py
index 79d1011..caa20c8 100644
--- a/swig/python/samples/validate_gpkg.py
+++ b/swig/python/samples/validate_gpkg.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 ###############################################################################
-# $Id: validate_gpkg.py 37981 2017-04-13 17:15:15Z rouault $
+# $Id: validate_gpkg.py 38103 2017-04-22 18:06:20Z rouault $
 #
 # Project:  GDAL/OGR
 # Purpose:  Test compliance of GeoPackage database w.r.t GeoPackage spec
@@ -61,6 +61,9 @@ class GPKGCheckException(Exception):
 
 class GPKGChecker:
 
+    EXT_GEOM_TYPES = ('CIRCULARSTRING', 'COMPOUNDCURVE', 'CURVEPOLYGON',
+                      'MULTICURVE', 'MULTISURFACE', 'CURVE', 'SURFACE')
+
     def __init__(self, filename, abort_at_first_error=True, verbose=False):
         self.filename = filename
         self.extended_pragma_info = False
@@ -308,8 +311,6 @@ class GPKGChecker:
         base_geom_types = ('GEOMETRY', 'POINT', 'LINESTRING', 'POLYGON',
                            'MULTIPOINT', 'MULTILINESTRING', 'MULTIPOLYGON',
                            'GEOMETRYCOLLECTION')
-        ext_geom_types = ('CIRCULARSTRING', 'COMPOUNDCURVE', 'CURVEPOLYGON',
-                          'MULTICURVE', 'MULTISURFACE', 'CURVE', 'SURFACE')
         cols = c.fetchall()
         found_geom = False
         count_pkid = 0
@@ -317,7 +318,8 @@ class GPKGChecker:
             if name == geom_column_name:
                 found_geom = True
                 self._assert(
-                    type in base_geom_types or type in ext_geom_types,
+                    type in base_geom_types or
+                    type in GPKGChecker.EXT_GEOM_TYPES,
                     25, ('invalid type (%s) for geometry ' +
                          'column of table %s') % (type, table_name))
                 self._assert(type == geometry_type_name, 31,
@@ -348,7 +350,7 @@ class GPKGChecker:
         self._assert(m in (0, 1, 2), 27, ("m value of %s is %d. " +
                      "Expected 0, 1 or 2") % (table_name, m))
 
-        if geometry_type_name in ext_geom_types:
+        if geometry_type_name in GPKGChecker.EXT_GEOM_TYPES:
             c.execute("SELECT 1 FROM gpkg_extensions WHERE "
                       "extension_name = 'gpkg_geom_%s' AND "
                       "table_name = ? AND column_name = ? AND "
@@ -358,7 +360,7 @@ class GPKGChecker:
                          "gpkg_geom_%s extension should be declared for "
                          "table %s" % (geometry_type_name, table_name))
 
-        wkb_geometries = base_geom_types + ext_geom_types
+        wkb_geometries = base_geom_types + GPKGChecker.EXT_GEOM_TYPES
         c.execute("SELECT %s FROM %s " %
                   (_esc_id(geom_column_name), _esc_id(table_name)))
         found_geom_types = set()
@@ -478,7 +480,7 @@ class GPKGChecker:
                          (table_name, str(found_geom_types)))
 
         for geom_type in found_geom_types:
-            if geom_type in ext_geom_types:
+            if geom_type in GPKGChecker.EXT_GEOM_TYPES:
                 c.execute("SELECT 1 FROM gpkg_extensions WHERE "
                           "extension_name = 'gpkg_geom_%s' AND "
                           "table_name = ? AND column_name = ? AND "
@@ -1207,12 +1209,44 @@ class GPKGChecker:
                                   "gpkg_extensions doesn't exist") %
                                  (column_name, table_name))
 
-        c.execute("SELECT extension_name FROM gpkg_extensions "
-                  "WHERE extension_name NOT LIKE 'gpkg_%'")
+        c.execute("SELECT extension_name FROM gpkg_extensions")
         rows = c.fetchall()
+        KNOWN_EXTENSIONS = ['gpkg_rtree_index',
+                            'gpkg_zoom_other',
+                            'gpkg_webp',
+                            'gpkg_metadata',
+                            'gpkg_schema',
+                            'gpkg_crs_wkt',
+                            'gpkg_elevation_tiles']
+        for geom_name in GPKGChecker.EXT_GEOM_TYPES:
+            KNOWN_EXTENSIONS += ['gpkg_geom_' + geom_name]
+
         for (extension_name,) in rows:
-            self._assert(False, 63,
-                         "extension_name %s not valid" % extension_name)
+
+            if extension_name.startswith('gpkg_'):
+                self._assert(extension_name in KNOWN_EXTENSIONS,
+                             62,
+                             "extension_name %s not valid" % extension_name)
+            else:
+                self._assert('_' in extension_name,
+                             62,
+                             "extension_name %s not valid" % extension_name)
+                author = extension_name[0:extension_name.find('_')]
+                ext_name = extension_name[extension_name.find('_')+1:]
+                for x in author:
+                    self._assert((x >= 'a' and x <= 'z') or
+                                 (x >= 'A' and x <= 'Z') or
+                                 (x >= '0' and x <= '9'),
+                                 62,
+                                 "extension_name %s not valid" %
+                                 extension_name)
+                for x in ext_name:
+                    self._assert((x >= 'a' and x <= 'z') or
+                                 (x >= 'A' and x <= 'Z') or
+                                 (x >= '0' and x <= '9') or x == '_',
+                                 62,
+                                 "extension_name %s not valid" %
+                                 extension_name)
 
         c.execute("SELECT extension_name, scope FROM gpkg_extensions "
                   "WHERE scope NOT IN ('read-write', 'write-only')")

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/gdal.git



More information about the Pkg-grass-devel mailing list