[spatialite-gui] 01/01: Imported Upstream version 2.0.0~devel

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Fri Jun 19 21:52:11 UTC 2015


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

sebastic pushed a commit to annotated tag upstream/2.0.0_devel
in repository spatialite-gui.

commit 10e67a0fe2ec74654efa0073bea93a5d48493041
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Fri Jun 19 22:58:04 2015 +0200

    Imported Upstream version 2.0.0~devel
---
 BlobExplorer.cpp                |   507 +-
 Classdef.h                      |  4269 +++++++++++++++-
 Dialogs.cpp                     |   348 +-
 DialogsGraph.cpp                |  1327 +++--
 Exif.cpp                        |     9 +-
 Main.cpp                        |  3278 ++++++++++--
 Makefile-static-Linux           |     1 -
 Makefile-static-MacOsX          |    10 +-
 Makefile-static-MinGW           |    47 +-
 Makefile.am                     |    14 +-
 Makefile.in                     |   388 +-
 MalformedGeoms.cpp              |    69 +-
 Network.cpp                     |  1164 ++++-
 Objects.cpp                     |   454 +-
 QueryView.cpp                   |   752 ++-
 QueryViewComposer.cpp           |     8 +
 Raster.cpp                      |  3169 ++++++++++++
 RasterSymbolizers.cpp           |  6005 ++++++++++++++++++++++
 ResultSetView.cpp               |   431 +-
 Shapefiles.cpp                  |    57 +-
 Styles.cpp                      |  6742 +++++++++++++++++++++++++
 TableTree.cpp                   |  3152 ++++++++----
 TextCsv.cpp                     |     2 +-
 VectorSymbolizers1.cpp          | 10242 ++++++++++++++++++++++++++++++++++++++
 VectorSymbolizers2.cpp          |  6184 +++++++++++++++++++++++
 Wfs.cpp                         |   244 +-
 aclocal.m4                      |   510 +-
 compile                         |   347 ++
 config.h.in                     |    31 +-
 configure                       |   808 ++-
 configure.ac                    |   134 +-
 gnome_resource/Makefile.in      |   125 +-
 icons/AttributionDisclaimer.txt |    29 +
 icons/Makefile.am               |     4 +-
 icons/Makefile.in               |   129 +-
 icons/connect_ro.xpm            |   146 +
 icons/coverage.xpm              |   154 +
 icons/coverage_tiles.xpm        |   133 +
 icons/security_lock.xpm         |   187 +
 icons/security_rdonly.xpm       |   189 +
 icons/security_relaxed.xpm      |   193 +
 icons/vector.xpm                |   195 +
 mac_resource/Makefile.in        |   125 +-
 win_resource/Makefile.in        |   125 +-
 44 files changed, 49354 insertions(+), 3083 deletions(-)

diff --git a/BlobExplorer.cpp b/BlobExplorer.cpp
index 65c6884..70338a8 100644
--- a/BlobExplorer.cpp
+++ b/BlobExplorer.cpp
@@ -30,7 +30,9 @@
 #include "wx/tokenzr.h"
 #include "wx/spinctrl.h"
 
-#include "gaiagraphics.h"
+#include "rasterlite2/rasterlite2.h"
+#include "rasterlite2/rl2svg.h"
+#include "rasterlite2/rl2graphics.h"
 
 BlobExplorerDialog::BlobExplorerDialog(MyFrame * parent, int blob_size,
                                        unsigned char *blob)
@@ -51,6 +53,7 @@ bool BlobExplorerDialog::Create(MyFrame * parent, int blob_size,
   BlobSize = blob_size;
   Blob = blob;
   BlobType = gaiaGuessBlobType(Blob, BlobSize);
+  IsTextFont = false;
   Geometry = NULL;
   IsSVG = false;
   XMLDocument = wxT("");
@@ -63,14 +66,19 @@ bool BlobExplorerDialog::Create(MyFrame * parent, int blob_size,
   GMLprecision = -1;
   GeoJSONoptions = 0;
   GeoJSONprecision = -1;
-  const void *img = NULL;
+  rl2RasterPtr raster = NULL;
   unsigned char *rgbaArray = NULL;
-  int width;
-  int height;
-  bool isRasterLiteRaw = false;
+  int rgbaSize;
+  unsigned int width;
+  unsigned int height;
+  unsigned char sample_type;
+  unsigned char pixel_type;
+  unsigned char num_bands;
 
   if (BlobType == GAIA_GEOMETRY_BLOB)
     Geometry = gaiaFromSpatiaLiteBlobWkb(Blob, BlobSize);
+  else if (BlobType == GAIA_GPB_BLOB)
+    Geometry = gaiaFromGeoPackageGeometryBlob(Blob, BlobSize);
   else if (BlobType == GAIA_XML_BLOB)
     {
 #ifdef ENABLE_LIBXML2           /* only if LIBXML2 is enabled */
@@ -89,32 +97,42 @@ bool BlobExplorerDialog::Create(MyFrame * parent, int blob_size,
         }
       if (gaiaIsSvgXmlBlob(Blob, BlobSize))
         {
-          /* handling the SVG preview */
+          // handling the SVG preview 
           char *svg = gaiaXmlTextFromBlob(Blob, BlobSize, 0);
           int svg_sz = strlen(svg);
           IsSVG = true;
           SvgSize = svg_sz;
-          void *svg_handle;
-          img = NULL;
-          if (gGraphCreateSVG((const unsigned char *) svg, svg_sz, &svg_handle)
-              == GGRAPH_OK)
-
+          rl2SvgPtr svg_handle =
+            rl2_create_svg((const unsigned char *) svg, svg_sz);
+          if (svg_handle != NULL)
             {
-              gGraphGetSVGDims(svg_handle, &SvgWidth, &SvgHeight);
-              double w = SvgWidth;
-              double h = SvgHeight;
-              while (w > 560.0 || h > 300.0)
+              if (rl2_get_svg_size(svg_handle, &SvgWidth, &SvgHeight) == RL2_OK)
                 {
-                  /* rescaling */
-                  w *= 0.9;
-                  h *= 0.9;
+                  double w = SvgWidth;
+                  double h = SvgHeight;
+                  if (w < 560.0 && h < 300.0)
+                    {
+                      while (w < 560.0 && h < 300.0)
+                        {
+                          // rescaling
+                          w *= 1.0001;
+                          h *= 1.0001;
+                        }
+                  } else
+                    {
+                      while (w > 560.0 || h > 300.0)
+                        {
+                          // rescaling
+                          w *= 0.9;
+                          h *= 0.9;
+                        }
+                    }
+                  double sz = w;
+                  if (h > sz)
+                    sz = h;
+                  raster = rl2_raster_from_svg(svg_handle, sz);
                 }
-              double sz = w;
-              if (h > sz)
-                sz = h;
-              if (gGraphImageFromSVG(svg_handle, sz, &img) != GGRAPH_OK)
-                img = NULL;
-              gGraphFreeSVG(svg_handle);
+              rl2_destroy_svg(svg_handle);
             }
           free(svg);
         }
@@ -126,50 +144,141 @@ bool BlobExplorerDialog::Create(MyFrame * parent, int blob_size,
           case GAIA_JPEG_BLOB:
           case GAIA_EXIF_BLOB:
           case GAIA_EXIF_GPS_BLOB:
-            if (gGraphImageFromMemBuf
-                (Blob, BlobSize, GGRAPH_IMAGE_JPEG, &img, 1) != GGRAPH_OK)
-              img = NULL;
+            raster = rl2_raster_from_jpeg(Blob, BlobSize);
             break;
           case GAIA_PNG_BLOB:
-            if (gGraphImageFromMemBuf(Blob, BlobSize, GGRAPH_IMAGE_PNG, &img, 1)
-                != GGRAPH_OK)
-              img = NULL;
+            raster = rl2_raster_from_png(Blob, BlobSize, 1);
             break;
           case GAIA_GIF_BLOB:
-            if (gGraphImageFromMemBuf(Blob, BlobSize, GGRAPH_IMAGE_GIF, &img, 1)
-                != GGRAPH_OK)
-              img = NULL;
+            raster = rl2_raster_from_gif(Blob, BlobSize);
             break;
           case GAIA_TIFF_BLOB:
-            if (gGraphImageFromMemBuf
-                (Blob, BlobSize, GGRAPH_IMAGE_TIFF, &img, 1) != GGRAPH_OK)
-              img = NULL;
+            raster = rl2_raster_from_tiff(Blob, BlobSize);
+            break;
+
+#ifndef OMIT_WEBP               /* only if WebP is supported */
+          case GAIA_WEBP_BLOB:
+            raster = rl2_raster_from_webp(Blob, BlobSize);
             break;
+#endif /* end WebP conditional */
+
+#ifndef	OMIT_OPENJPEG           /* only if OpenJpeg is supported */
+          case GAIA_JP2_BLOB:
+            if (rl2_get_jpeg2000_blob_type
+                (Blob, BlobSize, &sample_type, &pixel_type,
+                 &num_bands) == RL2_OK)
+              {
+                if ((sample_type == RL2_SAMPLE_UINT8
+                     && pixel_type == RL2_PIXEL_RGB && num_bands == 3)
+                    || (sample_type == RL2_SAMPLE_UINT8
+                        && pixel_type == RL2_PIXEL_GRAYSCALE && num_bands == 1))
+                  raster =
+                    rl2_raster_from_jpeg2000(Blob, BlobSize, sample_type,
+                                             pixel_type, num_bands);
+              }
+            break;
+#endif /* end OpenJpeg conditional */
           default:
-            if (gGraphIsRawImage(Blob, BlobSize) == GGRAPH_OK)
+            // testing for an eventual Text Font
+            int ret = rl2_is_valid_encoded_font(Blob, BlobSize);
+            if (ret == RL2_OK)
               {
-                /* this one is a RasterLite RAW image */
-                if (gGraphImageFromRawMemBuf(Blob, BlobSize, &img) != GGRAPH_OK)
-                  img = NULL;
+                IsTextFont = true;
+                char *str = rl2_get_encoded_font_family(Blob, BlobSize);
+                FontFamily = wxString::FromUTF8(str);
+                free(str);
+                str = rl2_get_encoded_font_style(Blob, BlobSize);
+                FontStyle = wxString::FromUTF8(str);
+                free(str);
+                if (rl2_is_encoded_font_bold(Blob, BlobSize) <= 0)
+                  IsFontBold = false;
+                else
+                  IsFontBold = true;
+                if (rl2_is_encoded_font_italic(Blob, BlobSize) <= 0)
+                  IsFontItalic = false;
                 else
-                  isRasterLiteRaw = true;
+                  IsFontItalic = true;
+                // creating the Font Preview
+                rl2GraphicsContextPtr ctx = rl2_graph_create_context(560, 290);
+                // white background initialization
+                rl2_graph_set_brush(ctx, 255, 255, 255, 255);
+                rl2_graph_draw_rectangle(ctx, -1, -1, 561, 291);
+                rl2GraphicsFontPtr font2 =
+                  rl2_graph_create_toy_font(NULL, 12.0, RL2_FONTSTYLE_NORMAL,
+                                            RL2_FONTWEIGHT_BOLD);
+                rl2_graph_font_set_color(font2, 255, 0, 0, 255);
+                const char *sample =
+                  "the quick brown fox jumps over the lazy dog";
+                double y = 5.0;
+                double pts[] =
+                  { 8.0, 12.0, 24.0, 36.0, 48.0, 60.0, 72.0, -1.0 };
+                double *ppts = pts;
+                while (1)
+                  {
+                    rl2GraphicsFontPtr font =
+                      rl2_graph_create_TrueType_font
+                      (MainFrame->GetRL2PrivateData(), Blob,
+                       BlobSize, *ppts);
+                    rl2_graph_set_font(ctx, font);
+                    char text[32];
+                    sprintf(text, "%1.0f", *ppts);
+                    double pre_x;
+                    double pre_y;
+                    double width;
+                    double height;
+                    double post_x;
+                    double post_y;
+                    double base_y;
+                    rl2_graph_get_text_extent(ctx, sample, &pre_x, &pre_y,
+                                              &width, &height, &post_x,
+                                              &post_y);
+                    base_y = height + post_y;
+                    rl2_graph_set_font(ctx, font2);
+                    rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &width,
+                                              &height, &post_x, &post_y);
+                    if ((height + post_y) > base_y)
+                      base_y = height + post_y;
+                    y += base_y + 2.0;
+                    if (y > 290.0)
+                      {
+                        rl2_graph_release_font(ctx);
+                        rl2_graph_destroy_font(font);
+                        break;
+                      }
+                    rl2_graph_draw_text(ctx, text, 20.0 - width, y, 0.0, 0.0,
+                                        0.0);
+                    rl2_graph_set_font(ctx, font);
+                    rl2_graph_draw_text(ctx, sample, 30, y, 0.0, 0.0, 0.0);
+                    ppts++;
+                    rl2_graph_release_font(ctx);
+                    rl2_graph_destroy_font(font);
+                    if (*ppts < 0.0)
+                      break;
+                  }
+                rl2_graph_destroy_font(font2);
+                unsigned char *rgb = rl2_graph_get_context_rgb_array(ctx);
+                rl2_graph_destroy_context(ctx);
+                raster =
+                  rl2_create_raster(560, 290, RL2_SAMPLE_UINT8, RL2_PIXEL_RGB,
+                                    3, rgb, 560 * 290 * 3, NULL, NULL, 0, NULL);
               }
             break;
         };
     }
-  if (img)
+  if (raster)
     {
-      if (gGraphGetImageDims(img, &width, &height) == GGRAPH_OK)
+      if (rl2_get_raster_size(raster, &width, &height) == RL2_OK)
         {
-          if (gGraphImageBufferReferenceRGBA(img, &rgbaArray) != GGRAPH_OK)
+          if (rl2_raster_data_to_RGBA(raster, &rgbaArray, &rgbaSize) != RL2_OK)
             rgbaArray = NULL;
         }
+      rl2_destroy_raster(raster);
     }
   if (rgbaArray)
     {
       // creating the Image from RGB array
-      int x;
-      int y;
+      unsigned int x;
+      unsigned int y;
       Image = new wxImage(width, height);
       unsigned char *p = rgbaArray;
       Image->SetAlpha();
@@ -198,8 +307,6 @@ bool BlobExplorerDialog::Create(MyFrame * parent, int blob_size,
             Image->SetRGB(x, y, 0, 0, 0);
         }
     }
-  if (img)
-    gGraphDestroyImage(img);
 
   if (wxPropertySheetDialog::Create(parent, wxID_ANY, wxT("BLOB explorer")) ==
       false)
@@ -208,7 +315,7 @@ bool BlobExplorerDialog::Create(MyFrame * parent, int blob_size,
 // creates individual panels
   wxPanel *hexadecimal = CreateHexadecimalPage(book);
   book->AddPage(hexadecimal, wxT("Hexadecimal dump"), true);
-  if (BlobType == GAIA_GEOMETRY_BLOB)
+  if (BlobType == GAIA_GEOMETRY_BLOB || BlobType == GAIA_GPB_BLOB)
     {
       wxPanel *geometry = CreateGeometryPage(book);
       book->AddPage(geometry, wxT("Geometry explorer"), false);
@@ -237,10 +344,19 @@ bool BlobExplorerDialog::Create(MyFrame * parent, int blob_size,
   if (BlobType == GAIA_JPEG_BLOB || BlobType == GAIA_EXIF_BLOB
       || BlobType == GAIA_EXIF_GPS_BLOB || BlobType == GAIA_PNG_BLOB
       || BlobType == GAIA_GIF_BLOB || BlobType == GAIA_TIFF_BLOB
-      || isRasterLiteRaw == true || IsSVG == true)
+#ifndef OMIT_WEBP               /* only if WebP is supported */
+      || BlobType == GAIA_WEBP_BLOB
+#endif
+#ifndef OMIT_OPENJPEG           /* only if OpenJpeg is supported */
+      || BlobType == GAIA_JP2_BLOB
+#endif
+      || IsSVG == true || IsTextFont == true)
     {
       wxPanel *image = CreateImagePage(book);
-      book->AddPage(image, wxT("Image"), false);
+      if (IsTextFont == true)
+        book->AddPage(image, wxT("Font Preview"), false);
+      else
+        book->AddPage(image, wxT("Image"), false);
     }
   CreateButtons(wxOK);
   LayoutDialog();
@@ -928,15 +1044,22 @@ wxPanel *BlobExplorerDialog::CreateImagePage(wxWindow * parent)
 // creating a control to show the image title
   wxBoxSizer *imgSizer = new wxBoxSizer(wxVERTICAL);
   boxSizer->Add(imgSizer, 0, wxALIGN_TOP | wxALL, 0);
+  wxString title1 = wxT("Image");
+  wxString title2 = wxT("Image preview");
+  if (IsTextFont == true)
+    {
+      title1 = wxT("TrueType Font");
+      title2 = wxT("Font Preview");
+    }
   wxStaticText *imageTitle = new wxStaticText(panel, ID_IMAGE_TITLE,
-                                              wxT("Image"),
+                                              title1,
                                               wxDefaultPosition,
                                               wxSize(560,
                                                      10));
   imgSizer->Add(imageTitle, 0, wxALIGN_LEFT | wxALL, 5);
 // creating a control to show the image
   wxStaticBox *exBox = new wxStaticBox(panel, ID_IMG_BOX,
-                                       wxT("Image preview"),
+                                       title2,
                                        wxDefaultPosition, wxDefaultSize);
   wxBoxSizer *exampleSizer = new wxStaticBoxSizer(exBox, wxHORIZONTAL);
   imgSizer->Add(exampleSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
@@ -959,7 +1082,7 @@ void BlobExplorerDialog::OnPageChanged(wxNotebookEvent & event)
         UpdateHexadecimalPage();
         break;
       case 1:
-        if (BlobType == GAIA_GEOMETRY_BLOB)
+        if (BlobType == GAIA_GEOMETRY_BLOB || BlobType == GAIA_GPB_BLOB)
           UpdateGeometryPage();
         else if (BlobType == GAIA_XML_BLOB)
           UpdateXmlDocumentPage();
@@ -973,7 +1096,7 @@ void BlobExplorerDialog::OnPageChanged(wxNotebookEvent & event)
           UpdateWKTPage();
         break;
       case 3:
-        if (IsSVG == true)
+        if (IsSVG == true || IsTextFont == true)
           UpdateImagePage();
         else
           UpdateEWKTPage();
@@ -1308,20 +1431,45 @@ void BlobExplorerDialog::UpdateImagePage()
                         Image->GetWidth(), Image->GetHeight(), BlobSize);
                 title = wxString::FromUTF8(dummy);
                 break;
+
+#ifndef OMIT_WEBP               /* only if WebP is supported */
+              case GAIA_WEBP_BLOB:
+                sprintf(dummy,
+                        "WEBP image     resolution: %d x %d          %d bytes",
+                        Image->GetWidth(), Image->GetHeight(), BlobSize);
+                title = wxString::FromUTF8(dummy);
+                break;
+#endif /* end WebP conditional */
+
+#ifndef OMIT_OPENJPEG           /* only if OpenJpeg is supported */
+              case GAIA_JP2_BLOB:
+                sprintf(dummy,
+                        "Jpeg2000 image     resolution: %d x %d          %d bytes",
+                        Image->GetWidth(), Image->GetHeight(), BlobSize);
+                title = wxString::FromUTF8(dummy);
+                break;
+#endif /* end OpenJpeg conditional */
+
               default:
-                if (gGraphIsRawImage(Blob, BlobSize) == GGRAPH_OK)
-                  {
-                    sprintf(dummy,
-                            "RasterLite RAW image     resolution: %d x %d          %d bytes",
-                            Image->GetWidth(), Image->GetHeight(), BlobSize);
-                    title = wxString::FromUTF8(dummy);
-                } else if (IsSVG == true)
+                if (IsSVG == true)
                   {
                     sprintf(dummy,
                             "SVG image     resolution: %1.2f x %1.2f          %d bytes",
                             SvgWidth, SvgHeight, SvgSize);
                     title = wxString::FromUTF8(dummy);
                   }
+                if (IsTextFont == true)
+                  {
+                    title = FontFamily + wxT("-") + FontStyle;
+                    if (IsFontBold == true)
+                      title += wxT("    bold=YES");
+                    else
+                      title += wxT("    bold=NO");
+                    if (IsFontItalic == true)
+                      title += wxT("    italic=YES");
+                    else
+                      title += wxT("    italic=NO");
+                  }
                 break;
             }
         }
@@ -2082,7 +2230,7 @@ void ImageShow::OnRightClick(wxMouseEvent & event)
 //
 // right click on the Image
 //
-  wxMenu *menu = new wxMenu();
+  wxMenu menu;
   wxMenuItem *menuItem;
   wxImage *Image = Parent->GetImage();
   if (Image)
@@ -2090,9 +2238,9 @@ void ImageShow::OnRightClick(wxMouseEvent & event)
       if (Image->IsOk() == true)
         {
           wxPoint pt = event.GetPosition();
-          menuItem = new wxMenuItem(menu, Image_Copy, wxT("&Copy"));
-          menu->Append(menuItem);
-          PopupMenu(menu, pt);
+          menuItem = new wxMenuItem(&menu, Image_Copy, wxT("&Copy"));
+          menu.Append(menuItem);
+          PopupMenu(&menu, pt);
         }
     }
 }
@@ -2185,3 +2333,230 @@ wxString MyHexList::OnGetItemText(long item, long column) const
     }
   return value;
 }
+
+TilePreviewDialog::TilePreviewDialog(MyFrame * parent, wxString & coverage,
+                                     int tile_id, int blob_size,
+                                     unsigned char *blob)
+{
+//
+// constructor; just calls Create()
+//
+  Create(parent, coverage, tile_id, blob_size, blob);
+}
+
+bool TilePreviewDialog::Create(MyFrame * parent, wxString & coverage,
+                               int tile_id, int blob_size, unsigned char *blob)
+{
+//
+// creating the dialog
+//
+  rl2RasterPtr raster = NULL;
+  unsigned char *rgbaArray = NULL;
+  int rgbaSize;
+  unsigned int width;
+  unsigned int height;
+  unsigned char sample_type;
+  unsigned char pixel_type;
+  unsigned char num_bands;
+  MainFrame = parent;
+  CoverageTable = coverage;
+  TileId = tile_id;
+  if (wxDialog::Create(parent, wxID_ANY, wxT("Raster Tile Preview")) == false)
+    return false;
+
+  int blob_type = gaiaGuessBlobType(blob, blob_size);
+  Image = NULL;
+  Painted = false;
+
+  switch (blob_type)
+    {
+      case GAIA_JPEG_BLOB:
+      case GAIA_EXIF_BLOB:
+      case GAIA_EXIF_GPS_BLOB:
+        raster = rl2_raster_from_jpeg(blob, blob_size);
+        break;
+      case GAIA_PNG_BLOB:
+        raster = rl2_raster_from_png(blob, blob_size, 1);
+        break;
+      case GAIA_GIF_BLOB:
+        raster = rl2_raster_from_gif(blob, blob_size);
+        break;
+      case GAIA_TIFF_BLOB:
+        raster = rl2_raster_from_tiff(blob, blob_size);
+        break;
+
+#ifndef OMIT_WEBP               /* only if WebP is supported */
+      case GAIA_WEBP_BLOB:
+        raster = rl2_raster_from_webp(blob, blob_size);
+        break;
+#endif /* end WebP conditional */
+
+#ifndef OMIT_OPENJPEG           /* only if OpenJpeg is supported */
+      case GAIA_JP2_BLOB:
+        if (rl2_get_jpeg2000_blob_type
+            (blob, blob_size, &sample_type, &pixel_type, &num_bands) == RL2_OK)
+          {
+            if ((sample_type == RL2_SAMPLE_UINT8 && pixel_type == RL2_PIXEL_RGB
+                 && num_bands == 3) || (sample_type == RL2_SAMPLE_UINT8
+                                        && pixel_type == RL2_PIXEL_GRAYSCALE
+                                        && num_bands == 1))
+              raster =
+                rl2_raster_from_jpeg2000(blob, blob_size, sample_type,
+                                         pixel_type, num_bands);
+          }
+        break;
+#endif /* end OpenJpeg conditional */
+    };
+  if (raster)
+    {
+      if (rl2_get_raster_size(raster, &width, &height) == RL2_OK)
+        {
+          if (rl2_raster_data_to_RGBA(raster, &rgbaArray, &rgbaSize) != RL2_OK)
+            rgbaArray = NULL;
+        }
+      if (raster != NULL)
+        rl2_destroy_raster(raster);
+    }
+  if (rgbaArray)
+    {
+      // creating the Image from RGB array
+      unsigned int x;
+      unsigned int y;
+      Image = new wxImage(width, height);
+      unsigned char *p = rgbaArray;
+      Image->SetAlpha();
+      for (y = 0; y < height; y++)
+        {
+          for (x = 0; x < width; x++)
+            {
+              unsigned char r = *p++;
+              unsigned char g = *p++;
+              unsigned char b = *p++;
+              unsigned char alpha = *p++;
+              Image->SetRGB(x, y, r, g, b);
+              Image->SetAlpha(x, y, alpha);
+            }
+        }
+      free(rgbaArray);
+  } else
+    {
+      // creating a default BLACK Image
+      int x;
+      int y;
+      Image = new wxImage(128, 128);
+      for (y = 0; y < 128; y++)
+        {
+          for (x = 0; x < 128; x++)
+            Image->SetRGB(x, y, 0, 0, 0);
+        }
+    }
+  delete[]blob;
+
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void TilePreviewDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// Coverage and TileId
+  wxBoxSizer *hdrSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(hdrSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxString hdr = wxT("Coverage: ") + CoverageTable;
+  hdr += wxT(" - TileID=");
+  char dummy[1024];
+  sprintf(dummy, "%d", TileId);
+  hdr += wxString::FromUTF8(dummy);
+  wxStaticText *coverageLabel = new wxStaticText(this, wxID_STATIC, hdr);
+  hdrSizer->Add(coverageLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+
+// creating a control to show the image
+  wxStaticBox *exBox = new wxStaticBox(this, ID_IMG_BOX,
+                                       wxT("Raster Tile preview"),
+                                       wxDefaultPosition, wxDefaultSize);
+  wxBoxSizer *exampleSizer = new wxStaticBoxSizer(exBox, wxHORIZONTAL);
+  boxSizer->Add(exampleSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBitmap *img = new wxStaticBitmap(this, ID_IMAGE, wxBitmap(),
+                                           wxDefaultPosition,
+                                           wxSize(480, 480), wxBORDER_SIMPLE);
+  exampleSizer->Add(img, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+
+// OK button
+  wxBoxSizer *okBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(okBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&OK"));
+  okBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handlers
+  Connect(wxID_ANY, wxEVT_PAINT,
+          (wxObjectEventFunction) & TilePreviewDialog::OnPaint);
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & TilePreviewDialog::OnOk);
+}
+
+void TilePreviewDialog::OnPaint(wxPaintEvent & WXUNUSED(event))
+{
+//
+// PAINT event: drawing the Tile Preview
+//
+  wxStaticBox *imgBox = (wxStaticBox *) FindWindow(ID_IMG_BOX);
+  ImageShow *imgShow = (ImageShow *) FindWindow(ID_IMAGE);
+  double horz;
+  double vert;
+  wxImage scaledImg;
+  wxSize sz;
+  wxSize box;
+  int boxX;
+  int boxY;
+  int posX;
+  int posY;
+  if (Image && Painted == false)
+    {
+      ::wxBeginBusyCursor();
+      if (Image->IsOk() == true)
+        {
+          horz = Image->GetWidth();
+          vert = Image->GetHeight();
+          sz = imgShow->GetSize();
+          box = imgBox->GetSize();
+          while (horz > sz.GetWidth() || vert > sz.GetHeight())
+            {
+              horz *= 0.9;
+              vert *= 0.9;
+            }
+          if (horz == Image->GetWidth() && vert == Image->GetHeight())
+            scaledImg = Image->Copy();
+          else
+            scaledImg =
+              Image->Scale((int) horz, (int) vert, wxIMAGE_QUALITY_HIGH);
+          wxBitmap bmp(scaledImg);
+          imgBox->GetPosition(&boxX, &boxY);
+          posX = (box.GetWidth() - (int) horz) / 2;
+          posY = (box.GetHeight() - (int) vert) / 2;
+          imgShow->SetSize(boxX + posX, boxY + posY, (int) horz, (int) vert);
+          imgShow->SetBitmap(bmp);
+          imgShow->Show(true);
+          Painted = true;
+        }
+      ::wxEndBusyCursor();
+    }
+}
+
+void TilePreviewDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
diff --git a/Classdef.h b/Classdef.h
index 0fd5a5f..5d36266 100644
--- a/Classdef.h
+++ b/Classdef.h
@@ -46,9 +46,12 @@
 #include <spatialite/gaiageo.h>
 #include <spatialite.h>
 #include <spatialite/gg_wfs.h>
+#include <spatialite/geopackage.h>
 
 #include <freexl.h>
 
+#include <rasterlite2/rasterlite2.h>
+
 //
 // functions for QSORT / BSEARCH
 //
@@ -79,10 +82,48 @@ DWORD WINAPI DoExecuteWfs(void *arg);
 void *DoExecuteWfs(void *arg);
 #endif
 
+//
+// functions for threaded Raster Import
+//
+#ifdef _WIN32
+DWORD WINAPI DoExecuteRasterLoad(void *arg);
+#else
+void *DoExecuteRasterLoad(void *arg);
+#endif
+
+//
+// functions for threaded Raster Style Import
+//
+#ifdef _WIN32
+DWORD WINAPI DoExecuteRasterStylesLoad(void *arg);
+#else
+void *DoExecuteRasterStylesLoad(void *arg);
+#endif
+
+//
+// functions for threaded Vector Style Import
+//
+#ifdef _WIN32
+DWORD WINAPI DoExecuteVectorStylesLoad(void *arg);
+#else
+void *DoExecuteVectorStylesLoad(void *arg);
+#endif
+
+// constants for UOM
+#define GUI_UOM_PIXEL	0xa0
+#define GUI_UOM_METRE	0xb0
+#define GUI_UOM_INCH	0xc0
+
+// constants for Preview Background
+#define GUI_PREVIEW_BACKGROUND_CHECKED	0xfa
+#define GUI_PREVIEW_BACKGROUND_WHITE	0xfb
+#define GUI_PREVIEW_BACKGROUND_BLACK	0xfc
+
 enum
 {
 // control IDs for main window and tree list control
   ID_Connect = 1,
+  ID_Connect_RO,
   ID_CreateNew,
   ID_Disconnect,
   ID_MemoryDbLoad,
@@ -118,12 +159,20 @@ enum
   Tree_NewIndex,
   Tree_NewTrigger,
   Tree_NewColumn,
+  Tree_NewRasterStyle,
+  Tree_ReloadRasterStyle,
+  Tree_UnregisterRasterStyle,
+  Tree_NewVectorStyle,
+  Tree_ReloadVectorStyle,
+  Tree_UnregisterVectorStyle,
   Tree_QueryViewComposer,
   Tree_Show,
   Tree_Drop,
   Tree_Rename,
   Tree_Select,
+  Tree_SelectTiles,
   Tree_Refresh,
+  Tree_RefreshDeferred,
   Tree_SpatialIndex,
   Tree_CheckSpatialIndex,
   Tree_RecoverSpatialIndex,
@@ -159,6 +208,39 @@ enum
   Tree_Detach,
   Tree_CheckGeom,
   Tree_SaneGeom,
+  Tree_SldSeRasterStyles,
+  Tree_SldSeVectorStyles,
+  Tree_ImportRaster,
+  Tree_Pyramidize,
+  Tree_PyramidizeMonolithic,
+  Tree_DePyramidize,
+  Tree_RasterDrop,
+  Tree_VectorRegister,
+  Tree_VectorUnregister,
+  Tree_CreateRasterCoverage,
+  Tree_UpdateRasterExtent,
+  Tree_UpdateRasterExtentAll,
+  Tree_UpdateVectorExtent,
+  Tree_UpdateVectorExtentAll,
+  Tree_Raster_SRIDs,
+  Tree_Vector_SRIDs,
+  Tree_Raster_Keywords,
+  Tree_Vector_Keywords,
+  Tree_RegisterExternalGraphic,
+  Tree_UnregisterExternalGraphic,
+  Tree_RegisterTextFont,
+  Tree_UnregisterTextFont,
+  Tree_RasterSymbolizerContrast,
+  Tree_RasterSymbolizerChannelRgb,
+  Tree_RasterSymbolizerChannelGray,
+  Tree_RasterSymbolizerCategorize,
+  Tree_RasterSymbolizerInterpolate,
+  Tree_RasterSymbolizerShadedRelief,
+  Tree_RasterSymbolizerMonochrome,
+  Tree_SimplePointSymbolizer,
+  Tree_SimpleLineSymbolizer,
+  Tree_SimplePolygonSymbolizer,
+  Tree_SimpleTextSymbolizer,
   Grid_Clear,
   Grid_All,
   Grid_Column,
@@ -181,6 +263,7 @@ enum
   Grid_ExpDif,
   Grid_ExpSylk,
   Grid_ExpDbf,
+  Grid_TilePreview,
   Image_Copy,
   Wfs_Copy,
   Wfs_Layer
@@ -244,6 +327,7 @@ enum
   ID_VIRTSHP_TABLE,
   ID_VIRTSHP_SRID,
   ID_VIRTSHP_CHARSET,
+  ID_VIRTSHP_TEXTDATES,
   ID_VIRTTXT_TABLE,
   ID_VIRTTXT_CHARSET,
   ID_VIRTTXT_TITLES,
@@ -253,6 +337,7 @@ enum
   ID_VIRTTXT_POINT,
   ID_VIRTDBF_TABLE,
   ID_VIRTDBF_CHARSET,
+  ID_VIRTDBF_TEXTDATES,
   ID_VIRTXL_TABLE,
   ID_VIRTXL_WORKSHEET,
   ID_VIRTXL_TITLES,
@@ -267,6 +352,7 @@ enum
   ID_LDSHP_GTYPE,
   ID_LDSHP_USER_PKEY,
   ID_LDSHP_PKCOL,
+  ID_LDSHP_TEXTDATES,
   ID_LDXL_TABLE,
   ID_LDXL_WORKSHEET,
   ID_LDXL_TITLES,
@@ -285,11 +371,13 @@ enum
   ID_LDDBF_CHARSET,
   ID_LDDBF_USER_PKEY,
   ID_LDDBF_PKCOL,
+  ID_LDDBF_TEXTDATES,
   ID_DMPSHP_CHARSET,
   ID_DMPTXT_CHARSET,
   ID_NET_TABLE,
   ID_NET_FROM,
   ID_NET_TO,
+  ID_NET_NO_GEOM,
   ID_NET_GEOM,
   ID_NET_LENGTH,
   ID_NET_COST,
@@ -300,6 +388,8 @@ enum
   ID_NET_NAME_ENABLE,
   ID_NET_NAME,
   ID_NET_A_STAR,
+  ID_NET_DATA,
+  ID_NET_VIRTUAL,
   ID_EXIF_PATH,
   ID_EXIF_FOLDER,
   ID_EXIF_METADATA,
@@ -482,8 +572,250 @@ enum
   ID_WFS_KEYWORD,
   ID_WFS_KEYFILTER,
   ID_WFS_KEYRESET,
+  ID_WFS_ENABLE_PROXY,
+  ID_WFS_PROXY,
   ID_WFS_STATUS,
-  ID_WFS_THREAD_FINISHED
+  ID_WFS_THREAD_FINISHED,
+  ID_SLD_SE_GRID,
+  ID_SLD_SE_REMOVE,
+  ID_SLD_SE_ADD,
+  ID_WAIT_VALIDATING,
+  ID_CVG_NAME,
+  ID_CVG_TITLE,
+  ID_CVG_ABSTRACT,
+  ID_CVG_SAMPLE,
+  ID_CVG_PIXEL,
+  ID_CVG_BANDS,
+  ID_CVG_COMPRESSION,
+  ID_CVG_QUALITY,
+  ID_CVG_RED,
+  ID_CVG_GREEN,
+  ID_CVG_BLUE,
+  ID_CVG_NIR,
+  ID_CVG_AUTO_NDVI,
+  ID_CVG_NODATA,
+  ID_CVG_WIDTH,
+  ID_CVG_SQTILE,
+  ID_CVG_HEIGHT,
+  ID_CVG_SRID,
+  ID_CVG_NOREF,
+  ID_CVG_HORZ_RES,
+  ID_CVG_SAME_RES,
+  ID_CVG_VERT_RES,
+  ID_CVG_STRICT_RES,
+  ID_CVG_MIXED_RES,
+  ID_CVG_PATHS,
+  ID_CVG_MD5,
+  ID_CVG_SUMMARY,
+  ID_LOAD_FORCE_SRID,
+  ID_LOAD_SRID,
+  ID_LOAD_WITH_WORLDFILE,
+  ID_LOAD_PYRAMIDIZE,
+  ID_LOAD_LIST_DONE,
+  ID_LOAD_ABORT,
+  ID_LOAD_RASTER_THREAD_FINISHED,
+  ID_LOAD_RASTER_START,
+  ID_LOAD_RASTER_STOP,
+  ID_PYRAMID_MODE,
+  ID_LOAD_STYLE_DONE,
+  ID_LOAD_RASTER_STYLE_THREAD_FINISHED,
+  ID_LOAD_RASTER_STYLE_START,
+  ID_LOAD_RASTER_STYLE_STOP,
+  ID_LOAD_RASTER_STYLE_SKIP,
+  ID_LOAD_VECTOR_STYLE_THREAD_FINISHED,
+  ID_LOAD_VECTOR_STYLE_START,
+  ID_LOAD_VECTOR_STYLE_STOP,
+  ID_LOAD_VECTOR_STYLE_SKIP,
+  ID_LOAD_EXTERNAL_THREAD_FINISHED,
+  ID_LOAD_EXTERNAL_DONE,
+  ID_LOAD_EXTERNAL_START,
+  ID_LOAD_EXTERNAL_STOP,
+  ID_LOAD_EXTERNAL_SKIP,
+  ID_LOAD_FONT_THREAD_FINISHED,
+  ID_LOAD_FONT_DONE,
+  ID_LOAD_FONT_START,
+  ID_LOAD_FONT_STOP,
+  ID_LOAD_FONT_SKIP,
+  ID_VECTOR_GRID,
+  ID_VECTOR_COVERAGE,
+  ID_VECTOR_TITLE,
+  ID_VECTOR_ABSTRACT,
+  ID_VECTOR_SRID_ADD,
+  ID_VECTOR_SRID_REMOVE,
+  ID_VECTOR_SRID,
+  ID_VECTOR_SRID_GRID,
+  ID_RASTER_SRID_ADD,
+  ID_RASTER_SRID_REMOVE,
+  ID_RASTER_SRID,
+  ID_RASTER_SRID_GRID,
+  ID_VECTOR_KEYWORD_ADD,
+  ID_VECTOR_KEYWORD_REMOVE,
+  ID_VECTOR_KEYWORD,
+  ID_VECTOR_KEYWORD_GRID,
+  ID_RASTER_KEYWORD_ADD,
+  ID_RASTER_KEYWORD_REMOVE,
+  ID_RASTER_KEYWORD,
+  ID_RASTER_KEYWORD_GRID,
+  ID_SYMBOLIZER_NAME,
+  ID_SYMBOLIZER_TITLE,
+  ID_SYMBOLIZER_ABSTRACT,
+  ID_SYMBOLIZER_OPACITY,
+  ID_SYMBOLIZER_RED,
+  ID_SYMBOLIZER_GREEN,
+  ID_SYMBOLIZER_BLUE,
+  ID_SYMBOLIZER_GRAY,
+  ID_SYMBOLIZER_CONTRAST,
+  ID_SYMBOLIZER_GAMMA,
+  ID_SYMBOLIZER_MAP,
+  ID_SYMBOLIZER_FALLBACK,
+  ID_SYMBOLIZER_VALUE,
+  ID_SYMBOLIZER_COLOR,
+  ID_SYMBOLIZER_PICKER_HEX,
+  ID_SYMBOLIZER_PICKER_BTN,
+  ID_SYMBOLIZER_SHADED,
+  ID_SYMBOLIZER_RELIEF,
+  ID_SYMBOLIZER_MINMAX_SCALE,
+  ID_SYMBOLIZER_MIN_SCALE,
+  ID_SYMBOLIZER_MAX_SCALE,
+  ID_SYMBOLIZER_UOM,
+  ID_SYMBOLIZER_STROKE1_ENABLE,
+  ID_SYMBOLIZER_STROKE1_OPACITY,
+  ID_SYMBOLIZER_STROKE1_PERPENDICULAR,
+  ID_SYMBOLIZER_STROKE1_TYPE,
+  ID_SYMBOLIZER_STROKE1_COLOR,
+  ID_SYMBOLIZER_STROKE1_PICKER_HEX,
+  ID_SYMBOLIZER_STROKE1_PICKER_BTN,
+  ID_SYMBOLIZER_STROKE1_GRAPHIC,
+  ID_SYMBOLIZER_STROKE1_ENABLE_REPLACEMENT,
+  ID_SYMBOLIZER_STROKE1_REPLACEMENT,
+  ID_SYMBOLIZER_STROKE1_REPLACEMENT_HEX,
+  ID_SYMBOLIZER_STROKE1_WIDTH,
+  ID_SYMBOLIZER_STROKE1_LINEJOIN,
+  ID_SYMBOLIZER_STROKE1_LINECAP,
+  ID_SYMBOLIZER_STROKE1_DASHARRAY,
+  ID_SYMBOLIZER_STROKE1_DASHOFFSET,
+  ID_SYMBOLIZER_STROKE2_ENABLE,
+  ID_SYMBOLIZER_STROKE2_OPACITY,
+  ID_SYMBOLIZER_STROKE2_PERPENDICULAR,
+  ID_SYMBOLIZER_STROKE2_TYPE,
+  ID_SYMBOLIZER_STROKE2_COLOR,
+  ID_SYMBOLIZER_STROKE2_PICKER_HEX,
+  ID_SYMBOLIZER_STROKE2_PICKER_BTN,
+  ID_SYMBOLIZER_STROKE2_GRAPHIC,
+  ID_SYMBOLIZER_STROKE2_ENABLE_REPLACEMENT,
+  ID_SYMBOLIZER_STROKE2_REPLACEMENT,
+  ID_SYMBOLIZER_STROKE2_REPLACEMENT_HEX,
+  ID_SYMBOLIZER_STROKE2_WIDTH,
+  ID_SYMBOLIZER_STROKE2_LINEJOIN,
+  ID_SYMBOLIZER_STROKE2_LINECAP,
+  ID_SYMBOLIZER_STROKE2_DASHARRAY,
+  ID_SYMBOLIZER_STROKE2_DASHOFFSET,
+  ID_SYMBOLIZER_STROKE3_ENABLE,
+  ID_SYMBOLIZER_STROKE3_OPACITY,
+  ID_SYMBOLIZER_STROKE3_PERPENDICULAR,
+  ID_SYMBOLIZER_STROKE3_TYPE,
+  ID_SYMBOLIZER_STROKE3_COLOR,
+  ID_SYMBOLIZER_STROKE3_PICKER_HEX,
+  ID_SYMBOLIZER_STROKE3_PICKER_BTN,
+  ID_SYMBOLIZER_STROKE3_GRAPHIC,
+  ID_SYMBOLIZER_STROKE3_ENABLE_REPLACEMENT,
+  ID_SYMBOLIZER_STROKE3_REPLACEMENT,
+  ID_SYMBOLIZER_STROKE3_REPLACEMENT_HEX,
+  ID_SYMBOLIZER_STROKE3_WIDTH,
+  ID_SYMBOLIZER_STROKE3_LINEJOIN,
+  ID_SYMBOLIZER_STROKE3_LINECAP,
+  ID_SYMBOLIZER_STROKE3_DASHARRAY,
+  ID_SYMBOLIZER_STROKE3_DASHOFFSET,
+  ID_SYMBOLIZER_FILL1_ENABLE,
+  ID_SYMBOLIZER_FILL1_OPACITY,
+  ID_SYMBOLIZER_FILL1_TYPE,
+  ID_SYMBOLIZER_FILL1_COLOR,
+  ID_SYMBOLIZER_FILL1_PICKER_HEX,
+  ID_SYMBOLIZER_FILL1_PICKER_BTN,
+  ID_SYMBOLIZER_FILL1_GRAPHIC,
+  ID_SYMBOLIZER_FILL1_ENABLE_REPLACEMENT,
+  ID_SYMBOLIZER_FILL1_REPLACEMENT,
+  ID_SYMBOLIZER_FILL1_REPLACEMENT_HEX,
+  ID_SYMBOLIZER_FILL2_ENABLE,
+  ID_SYMBOLIZER_FILL2_OPACITY,
+  ID_SYMBOLIZER_FILL2_TYPE,
+  ID_SYMBOLIZER_FILL2_COLOR,
+  ID_SYMBOLIZER_FILL2_PICKER_HEX,
+  ID_SYMBOLIZER_FILL2_PICKER_BTN,
+  ID_SYMBOLIZER_FILL2_GRAPHIC,
+  ID_SYMBOLIZER_FILL2_ENABLE_REPLACEMENT,
+  ID_SYMBOLIZER_FILL2_REPLACEMENT,
+  ID_SYMBOLIZER_FILL2_REPLACEMENT_HEX,
+  ID_SYMBOLIZER_POLYGON1_DISPLACEMENT_X,
+  ID_SYMBOLIZER_POLYGON1_DISPLACEMENT_Y,
+  ID_SYMBOLIZER_POLYGON1_PERPENDICULAR,
+  ID_SYMBOLIZER_POLYGON2_ENABLE,
+  ID_SYMBOLIZER_POLYGON2_DISPLACEMENT_X,
+  ID_SYMBOLIZER_POLYGON2_DISPLACEMENT_Y,
+  ID_SYMBOLIZER_POLYGON2_PERPENDICULAR,
+  ID_SYMBOLIZER_SIZE,
+  ID_SYMBOLIZER_ROTATION,
+  ID_SYMBOLIZER_DISPLACEMENT_X,
+  ID_SYMBOLIZER_DISPLACEMENT_Y,
+  ID_SYMBOLIZER_ANCHOR_X,
+  ID_SYMBOLIZER_ANCHOR_Y,
+  ID_SYMBOLIZER_TYPE,
+  ID_SYMBOLIZER_GRAPHIC,
+  ID_SYMBOLIZER_MARK,
+  ID_SYMBOLIZER_ENABLE_COLOR_REPLACEMENT,
+  ID_SYMBOLIZER_COLOR_REPLACEMENT,
+  ID_SYMBOLIZER_COLOR_REPLACEMENT_HEX,
+  ID_SYMBOLIZER_REPLACEMENT_PICKER_BTN,
+  ID_ONLY_RESCALE_SVG_SYMBOLS,
+  ID_SYMBOLIZER_FILL_ENABLE,
+  ID_SYMBOLIZER_FILL_COLOR,
+  ID_SYMBOLIZER_FILL_PICKER_HEX,
+  ID_SYMBOLIZER_FILL_PICKER_BTN,
+  ID_SYMBOLIZER_STROKE_ENABLE,
+  ID_SYMBOLIZER_STROKE_COLOR,
+  ID_SYMBOLIZER_STROKE_PICKER_HEX,
+  ID_SYMBOLIZER_STROKE_PICKER_BTN,
+  ID_SYMBOLIZER_STROKE_WIDTH,
+  ID_SYMBOLIZER_STROKE_LINEJOIN,
+  ID_SYMBOLIZER_STROKE_LINECAP,
+  ID_SYMBOLIZER_STROKE_DASHARRAY,
+  ID_SYMBOLIZER_STROKE_DASHOFFSET,
+  ID_SYMBOLIZER_LABEL,
+  ID_SYMBOLIZER_FONT,
+  ID_SYMBOLIZER_FONT_OPACITY,
+  ID_SYMBOLIZER_HALO_ENABLE,
+  ID_SYMBOLIZER_HALO_OPACITY,
+  ID_SYMBOLIZER_HALO_RADIUS,
+  ID_SYMBOLIZER_HALO_COLOR,
+  ID_SYMBOLIZER_HALO_PICKER_HEX,
+  ID_SYMBOLIZER_HALO_PICKER_BTN,
+  ID_SYMBOLIZER_PERPENDICULAR,
+  ID_SYMBOLIZER_IS_REPEATED,
+  ID_SYMBOLIZER_INITIAL_GAP,
+  ID_SYMBOLIZER_GAP,
+  ID_SYMBOLIZER_IS_ALIGNED,
+  ID_SYMBOLIZER_GENERALIZE,
+  ID_SYMBOLIZER_PREVIEW,
+  ID_SYMBOLIZER_BACKGROUND,
+  ID_SYMBOLIZER_CROSSHAIR,
+  ID_SYMBOLIZER_REFLINE,
+  ID_SYMBOLIZER_INSERT,
+  ID_SYMBOLIZER_EXPORT,
+  ID_SYMBOLIZER_COPY,
+  ID_SYMBOLIZER_ADD,
+  ID_SYMBOLIZER_REMOVE,
+  ID_PANE_MAIN,
+  ID_PANE_STROKE1,
+  ID_PANE_STROKE2,
+  ID_PANE_STROKE3,
+  ID_PANE_FILL1,
+  ID_PANE_FILL2,
+  ID_PANE_POSITION,
+  ID_PANE_GRAPHIC,
+  ID_PANE_MARK,
+  ID_PANE_FONT,
+  ID_PANE_PLACEMENT,
+  ID_PANE_PREVIEW
 };
 
 enum
@@ -492,6 +824,7 @@ enum
   MY_TABLE = 0,
   MY_VTABLE,
   MY_VIEW,
+  MY_TILE_DATA,
   MY_COLUMN,
   MY_VIEW_COLUMN,
   MY_VIRTUAL_COLUMN,
@@ -502,6 +835,7 @@ enum
   MY_VIEW_GEOMETRY_INDEX,
   MY_VIEW_GEOMETRY_CACHED,
   MY_VIRTUAL_GEOMETRY,
+  MY_VIRTUAL_GPKG_GEOMETRY,
   MY_INDEX,
   MY_TRIGGER,
   MY_ATTACHED,
@@ -517,7 +851,7 @@ enum
 // control IDs for timers
   ID_AUTO_SAVE_TIMER = 20000,
   ID_DB_STATUS_TIMER,
-  ID_WFS_TIMER,
+  ID_WFS_TIMER
 };
 
 enum
@@ -589,6 +923,7 @@ class TopologySet
 {
 //
 // a class representing a full Topology Set
+//
 private:
   wxString Prefix;
   wxString CoordDims;
@@ -635,6 +970,111 @@ public:
   }
 };
 
+class RasterCoverageItem
+{
+//
+// a class wrapping a Raster Coverage related Table or View
+//
+private:
+  wxString Name;
+  bool TileData;
+  RasterCoverageItem *Next;
+public:
+    RasterCoverageItem(wxString & name, bool tile_data);
+   ~RasterCoverageItem()
+  {;
+  }
+  wxString & GetName()
+  {
+    return Name;
+  }
+  bool IsTileData()
+  {
+    return TileData;
+  }
+  void SetNext(RasterCoverageItem * next)
+  {
+    Next = next;
+  }
+  RasterCoverageItem *GetNext()
+  {
+    return Next;
+  }
+};
+
+class RasterCoverageSet
+{
+//
+// a class representing a full Raster Coverage Set
+//
+private:
+  wxString Name;
+  int Srid;
+public:
+    RasterCoverageSet(const char *name, int srid);
+   ~RasterCoverageSet()
+  {;
+  }
+  wxString & GetName()
+  {
+    return Name;
+  }
+  int GetSrid()
+  {
+    return Srid;
+  }
+};
+
+class VectorCoverageItem
+{
+//
+// a class wrapping a Vector Coverage related Table or View
+//
+private:
+  wxString Name;
+  VectorCoverageItem *Next;
+public:
+    VectorCoverageItem(wxString & name);
+   ~VectorCoverageItem()
+  {;
+  }
+  wxString & GetName()
+  {
+    return Name;
+  }
+  void SetNext(VectorCoverageItem * next)
+  {
+    Next = next;
+  }
+  VectorCoverageItem *GetNext()
+  {
+    return Next;
+  }
+};
+
+class VectorCoverageSet
+{
+//
+// a class representing a full Vector Coverage Set
+//
+private:
+  wxString Name;
+  int Srid;
+public:
+    VectorCoverageSet(const char *name, int srid);
+   ~VectorCoverageSet()
+  {;
+  }
+  wxString & GetName()
+  {
+    return Name;
+  }
+  int GetSrid()
+  {
+    return Srid;
+  }
+};
+
 class MyObject:public wxTreeItemData
 {
 //
@@ -646,12 +1086,14 @@ private:
   wxString Name;                // the object name
   wxString Column;              // the column name [optional]
   bool Temporary;               // the TMP switch
+  bool Coverage;                // TRUE only if Raster Coverage related
 public:
     MyObject(int type, wxString & name);
-    MyObject(int type, wxString & name, bool tmp);
+    MyObject(int type, wxString & name, bool tmp, bool coverage = false);
     MyObject(int type, wxString & dbAlias, wxString & name, bool tmp);
     MyObject(int type, wxString & name, wxString & column);
-    MyObject(int type, bool attached, wxString & dbAlias, wxString & name);
+    MyObject(int type, bool attached, wxString & dbAlias, wxString & name,
+             bool coverage = false);
     virtual ~ MyObject()
   {;
   }
@@ -682,6 +1124,10 @@ public:
     else
       return false;
   }
+  bool IsCoverage()
+  {
+    return Coverage;
+  }
 };
 
 class MyColumnInfo
@@ -693,6 +1139,7 @@ private:
   wxString Name;                // the column name
   bool PrimaryKey;              // Primary Key column
   bool Geometry;                // Geometry column
+  bool GPKGGeometry;            // Geometry column
   bool GeometryIndex;           // Geometry column + SpatialIndex
   bool MbrCache;                // Geometry column + MbrCache
   MyColumnInfo *Next;           // pointer to next element into the linked list
@@ -713,10 +1160,18 @@ public:
   {
     Geometry = true;
   }
+  void SetGPKGGeometry()
+  {
+    GPKGGeometry = true;
+  }
   bool IsGeometry()
   {
     return Geometry;
   }
+  bool IsGPKGGeometry()
+  {
+    return GPKGGeometry;
+  }
   void SetGeometryIndex()
   {
     GeometryIndex = true;
@@ -768,6 +1223,8 @@ public:
   {
     return Next;
   }
+  bool ContainsOnlyPrimaryKeyColumns(sqlite3 * sqlite, wxString & indexName,
+                                     MyColumnInfo * first_column);
 };
 
 class MyTriggerInfo
@@ -836,6 +1293,7 @@ public:
   {
     return FirstTrigger;
   }
+  void CheckGPKG(class MyFrame * MainFrame, sqlite3 * handle, wxString & table);
 };
 
 class MyViewInfo
@@ -1142,191 +1600,166 @@ class MyApp:public wxApp
   virtual bool OnInit();
 };
 
-class DuplColumn
+class Topology
 {
 //
-// a column value in a duplicated row
+// Topology container
 //
 private:
-  int Pos;
-  wxString Name;
-  int Type;
-  sqlite3_int64 IntValue;
-  double DblValue;
-  const char *TxtValue;
-  const void *Blob;
-  int Size;
-  int QueryPos;
-  DuplColumn *Next;
+  wxTreeItemId TopologyNode;
+  TopologySet TopologyItems;
+  Topology *Next;
 public:
-    DuplColumn(int pos, wxString & name)
-  {
-    Pos = pos;
-    Name = name;
-    Type = SQLITE_NULL;
-    Next = NULL;
-  }
-   ~DuplColumn()
+    Topology(class MyTableTree * tree, wxTreeItemId & root,
+             TopologySet * topology);
+   ~Topology()
   {;
   }
-  int GetPos()
-  {
-    return Pos;
-  }
-  wxString & GetName()
-  {
-    return Name;
-  }
-  void SetValue(sqlite3_int64 value)
-  {
-    Type = SQLITE_INTEGER;
-    IntValue = value;
-  }
-  void SetValue(double value)
-  {
-    Type = SQLITE_FLOAT;
-    DblValue = value;
-  }
-  void SetValue(const char *value)
-  {
-    Type = SQLITE_TEXT;
-    TxtValue = value;
-  }
-  void SetValue(const void *blob, int size)
-  {
-    Type = SQLITE_BLOB;
-    Blob = blob;
-    Size = size;
-  }
-  void SetValue(void)
+  wxTreeItemId *Check(wxString & table);
+  Topology *GetNext()
   {
-    Type = SQLITE_NULL;
+    return Next;
   }
-  int GetType()
+  void SetNext(Topology * next)
   {
-    return Type;
+    Next = next;
   }
-  sqlite3_int64 GetIntValue()
+};
+
+class TopologyList
+{
+//
+// Topology container
+//
+private:
+  Topology * First;
+  Topology *Last;
+  int Count;
+public:
+    TopologyList()
   {
-    return IntValue;
+    First = NULL;
+    Last = NULL;
+    Count = 0;
   }
-  double GetDblValue()
+   ~TopologyList()
   {
-    return DblValue;
+    Flush();
   }
-  const char *GetTxtValue()
+  void Flush();
+  void Add(class MyTableTree * tree, wxTreeItemId & root,
+           TopologySet * topology);
+  wxTreeItemId *FindNode(wxString & table);
+  int GetCount()
   {
-    return TxtValue;
+    return Count;
   }
-  bool CheckBlob(const void *blob, int size);
-  void SetQueryPos(int pos)
-  {
-    QueryPos = pos;
+};
+
+class RasterCoverage
+{
+//
+// Raster Coverage container
+//
+private:
+  wxString Name;
+  wxTreeItemId CoverageNode;
+  RasterCoverage *Next;
+public:
+    RasterCoverage(class MyTableTree * tree, wxTreeItemId & root,
+                   wxString & coverage, int srid);
+   ~RasterCoverage()
+  {;
   }
-  int GetQueryPos()
+  wxTreeItemId *Check(wxString & table, bool * tile_data);
+  RasterCoverage *GetNext()
   {
-    return QueryPos;
+    return Next;
   }
-  void SetNext(DuplColumn * next)
+  void SetNext(RasterCoverage * next)
   {
     Next = next;
   }
-  DuplColumn *GetNext()
-  {
-    return Next;
-  }
 };
 
-class DuplRow
+class RasterCoverageList
 {
 //
-// a duplicated row with column values
+// Raster Coverage container
 //
 private:
+  RasterCoverage * First;
+  RasterCoverage *Last;
   int Count;
-  DuplColumn *First;
-  DuplColumn *Last;
-  wxString Table;
 public:
-    DuplRow()
+    RasterCoverageList()
   {
-    Count = 0;
     First = NULL;
     Last = NULL;
+    Count = 0;
   }
-   ~DuplRow();
-  void SetTable(wxString & table)
-  {
-    Table = table;
-  }
-  wxString & GetTable()
+   ~RasterCoverageList()
   {
-    return Table;
+    Flush();
   }
-  void Add(wxString & name);
-  void SetValue(int pos, sqlite3_int64 value);
-  void SetValue(int pos, double value);
-  void SetValue(int pos, const char *value);
-  void SetValue(int pos, const void *blob, int size);
-  void SetValue(int pos);
-  void ResetQueryPos();
-  bool CheckBlob(int pos, const void *blob, int size);
-  DuplColumn *GetFirst()
+  void Flush();
+  void Add(class MyTableTree * tree, wxTreeItemId & root,
+           wxString & coverage, int srid);
+  wxTreeItemId *FindNode(wxString & table, bool * tile_data);
+  int GetCount()
   {
-    return First;
+    return Count;
   }
 };
 
-class Topology
+class VectorCoverage
 {
 //
-// Topology container
+// Vector Coverage container
 //
 private:
-  wxTreeItemId TopologyNode;
-  TopologySet TopologyItems;
-  Topology *Next;
+  wxString Name;
+  wxTreeItemId CoverageNode;
+  VectorCoverage *Next;
 public:
-    Topology(class MyTableTree * tree, wxTreeItemId & root,
-             TopologySet * topology);
-   ~Topology()
+    VectorCoverage(class MyTableTree * tree, wxTreeItemId & root,
+                   wxString & coverage, int srid);
+   ~VectorCoverage()
   {;
   }
-  wxTreeItemId *Check(wxString & table);
-  Topology *GetNext()
+  VectorCoverage *GetNext()
   {
     return Next;
   }
-  void SetNext(Topology * next)
+  void SetNext(VectorCoverage * next)
   {
     Next = next;
   }
 };
 
-class TopologyList
+class VectorCoverageList
 {
 //
-// Topology container
+// Vector Coverage container
 //
 private:
-  Topology * First;
-  Topology *Last;
+  VectorCoverage * First;
+  VectorCoverage *Last;
   int Count;
 public:
-    TopologyList()
+    VectorCoverageList()
   {
     First = NULL;
     Last = NULL;
     Count = 0;
   }
-   ~TopologyList()
+   ~VectorCoverageList()
   {
     Flush();
   }
   void Flush();
   void Add(class MyTableTree * tree, wxTreeItemId & root,
-           TopologySet * topology);
-  wxTreeItemId *FindNode(wxString & table);
+           wxString & coverage, int srid);
   int GetCount()
   {
     return Count;
@@ -1342,6 +1775,8 @@ private:
   wxString dbAlias;
   wxTreeItemId rootUserData;
   wxTreeItemId rootTopologies;
+  wxTreeItemId rootRasterCoverages;
+  wxTreeItemId rootVectorCoverages;
   wxTreeItemId rootStyling;
   wxTreeItemId rootIsoMetadata;
   wxTreeItemId rootMetadata;
@@ -1349,6 +1784,7 @@ private:
   wxTreeItemId rootSpatialIndex;
 public:
     RootNodes(wxString & alias, wxTreeItemId userData, wxTreeItemId topologies,
+              wxTreeItemId raster_coverages, wxTreeItemId vector_coverages,
               wxTreeItemId styling, wxTreeItemId isoMetadata,
               wxTreeItemId metadata, wxTreeItemId internal,
               wxTreeItemId spatialIndex)
@@ -1356,6 +1792,8 @@ public:
     dbAlias = alias;
     rootUserData = userData;
     rootTopologies = topologies;
+    rootRasterCoverages = raster_coverages;
+    rootVectorCoverages = vector_coverages;
     rootStyling = styling;
     rootIsoMetadata = isoMetadata;
     rootMetadata = metadata;
@@ -1377,6 +1815,14 @@ public:
   {
     return rootTopologies;
   }
+  wxTreeItemId & GetRootRasterCoverages()
+  {
+    return rootRasterCoverages;
+  }
+  wxTreeItemId & GetRootVectorCoverages()
+  {
+    return rootVectorCoverages;
+  }
   wxTreeItemId & GetRootStyling()
   {
     return rootStyling;
@@ -1409,17 +1855,27 @@ private:
   wxTreeItemId Root;            // the root node
   wxTreeItemId RootUserData;
   wxTreeItemId RootTopologies;
+  wxTreeItemId RootRasterCoverages;
+  wxTreeItemId RootVectorCoverages;
   wxTreeItemId RootStyling;
   wxTreeItemId RootIsoMetadata;
   TopologyList Topologies;
+  RasterCoverageList RasterCoverages;
+  VectorCoverageList VectorCoverages;
+  TopologyList AltTopologies;
+  RasterCoverageList AltRasterCoverages;
+  VectorCoverageList AltVectorCoverages;
   wxTreeItemId RootMetadata;
   wxTreeItemId RootInternal;
   wxTreeItemId RootSpatialIndex;
   wxImageList *Images;          // the images list
   wxTreeItemId CurrentItem;     // the tree item holding the current context menu
-  bool doDeleteDuplicates(wxString & sql1, wxString & sql2, DuplRow * values,
-                          int *count);
-  bool doDeleteDuplicates2(sqlite3_stmt * stmt1, DuplRow * values, int *count);
+  wxString CurrentRasterCoverageName;
+  wxString CurrentVectorCoverageName;
+  void ExpandTable(wxTreeItemId & item);
+  void ExpandView(wxTreeItemId & item);
+  void ExpandAttachedTable(wxTreeItemId & item);
+  void ExpandAttachedView(wxTreeItemId & item);
 public:
     MyTableTree()
   {;
@@ -1433,19 +1889,26 @@ public:
     SetItemText(Root, path);
   }
   void FlushAll();
-  wxTreeItemId & GetRootNode(wxString & tableName);
-  wxTreeItemId & GetRootNode(wxString & tableName, RootNodes * nodes);
-  void AddTable(wxString & tableName, bool virtualTable, bool tmp);
-  void AddView(wxString & viewName, bool tmp);
+  wxTreeItemId & GetRootNode(wxString & tableName, bool * is_coverage =
+                             NULL, bool * tile_data = NULL);
+  wxTreeItemId & GetAltRootNode(wxString & tableName, RootNodes * nodes,
+                                bool * is_coverage = NULL, bool * tile_data =
+                                NULL);
+  void AddTable(wxString & tableName, bool virtualTable, bool geometry,
+                bool tmp);
+  void AddView(wxString & viewName, bool geometry, bool tmp);
   wxTreeItemId & AddAttached(wxString & dbAlias, wxString & path);
   void AddTable(wxString & dbAlias, wxString & tableName,
-                bool virtualTable, RootNodes * list);
-  void AddView(wxString & dbAlias, wxString & viewName, RootNodes * list);
+                bool virtualTable, bool geometry, RootNodes * list);
+  void AddView(wxString & dbAlias, wxString & viewName, bool geometry,
+               RootNodes * list);
   void ExpandRoot()
   {
     Expand(Root);
     Expand(RootUserData);
     CollapseAllChildren(RootTopologies);
+    CollapseAllChildren(RootRasterCoverages);
+    CollapseAllChildren(RootVectorCoverages);
     CollapseAllChildren(RootStyling);
     CollapseAllChildren(RootIsoMetadata);
     Collapse(RootMetadata);
@@ -1456,11 +1919,48 @@ public:
   {
     Topologies.Add(this, RootTopologies, topology);
   }
-  void AddTopology(wxTreeItemId & rootTopologies, TopologySet * topology)
+  void AddAltTopology(wxTreeItemId & rootTopologies, TopologySet * topology)
   {
-    Topologies.Add(this, rootTopologies, topology);
+    AltTopologies.Add(this, rootTopologies, topology);
   }
   void DeleteTopologies(wxTreeItemId & root_topologies);
+  void DeleteAltTopologies(void)
+  {
+    AltTopologies.Flush();
+  }
+  void AddRasterCoverage(RasterCoverageSet * coverage)
+  {
+    RasterCoverages.Add(this, RootRasterCoverages, coverage->GetName(),
+                        coverage->GetSrid());
+  }
+  void AddAltRasterCoverage(wxTreeItemId & rootRasterCoverages,
+                            RasterCoverageSet * coverage)
+  {
+    AltRasterCoverages.Add(this, rootRasterCoverages, coverage->GetName(),
+                           coverage->GetSrid());
+  }
+  void AddVectorCoverage(VectorCoverageSet * coverage)
+  {
+    VectorCoverages.Add(this, RootVectorCoverages, coverage->GetName(),
+                        coverage->GetSrid());
+  }
+  void AddAltVectorCoverage(wxTreeItemId & rootVectorCoverages,
+                            VectorCoverageSet * coverage)
+  {
+    AltVectorCoverages.Add(this, rootVectorCoverages, coverage->GetName(),
+                           coverage->GetSrid());
+  }
+  bool GetCurrentlySelectedTable(wxString & table_name);
+  void DeleteRasterCoverages(wxTreeItemId & root_coverages);
+  void DeleteVectorCoverages(wxTreeItemId & root_coverages);
+  void DeleteAltRasterCoverages(void)
+  {
+    AltRasterCoverages.Flush();
+  }
+  void DeleteAltVectorCoverages(void)
+  {
+    AltVectorCoverages.Flush();
+  }
   void OnSelChanged(wxTreeEvent & event);
   void OnRightClick(wxTreeEvent & event);
   void OnCmdQueryViewComposer(wxCommandEvent & event);
@@ -1469,11 +1969,48 @@ public:
   void OnCmdNewIndex(wxCommandEvent & event);
   void OnCmdNewTrigger(wxCommandEvent & event);
   void OnCmdNewColumn(wxCommandEvent & event);
+  void OnCmdNewRasterStyle(wxCommandEvent & event);
+  void OnCmdReloadRasterStyle(wxCommandEvent & event);
+  void OnCmdUnregisterRasterStyle(wxCommandEvent & event);
+  void OnCmdRegisterExternalGraphic(wxCommandEvent & event);
+  void OnCmdUnregisterExternalGraphic(wxCommandEvent & event);
+  void OnCmdRegisterTextFont(wxCommandEvent & event);
+  void OnCmdUnregisterTextFont(wxCommandEvent & event);
+  void OnCmdNewVectorStyle(wxCommandEvent & event);
+  void OnCmdReloadVectorStyle(wxCommandEvent & event);
+  void OnCmdUnregisterVectorStyle(wxCommandEvent & event);
+  void OnCmdRasterSymbolizerContrast(wxCommandEvent & event);
+  void OnCmdRasterSymbolizerChannelRgb(wxCommandEvent & event);
+  void OnCmdRasterSymbolizerChannelGray(wxCommandEvent & event);
+  void OnCmdRasterSymbolizerCategorize(wxCommandEvent & event);
+  void OnCmdRasterSymbolizerInterpolate(wxCommandEvent & event);
+  void OnCmdRasterSymbolizerShadedRelief(wxCommandEvent & event);
+  void OnCmdRasterSymbolizerMonochrome(wxCommandEvent & event);
+  void OnCmdSimpleLineSymbolizer(wxCommandEvent & event);
+  void OnCmdSimplePolygonSymbolizer(wxCommandEvent & event);
+  void OnCmdSimplePointSymbolizer(wxCommandEvent & event);
+  void OnCmdSimpleTextSymbolizer(wxCommandEvent & event);
+  void OnCmdImportRaster(wxCommandEvent & event);
+  void OnCmdPyramidize(wxCommandEvent & event);
+  void OnCmdPyramidizeMonolithic(wxCommandEvent & event);
+  void OnCmdDePyramidize(wxCommandEvent & event);
+  void OnCmdRasterDrop(wxCommandEvent & event);
+  void OnCmdRasterSRIDs(wxCommandEvent & event);
+  void OnCmdRasterKeywords(wxCommandEvent & event);
+  void OnCmdUpdateRasterExtent(wxCommandEvent & event);
+  void OnCmdUpdateRasterExtentAll(wxCommandEvent & event);
+  void OnCmdVectorUnregister(wxCommandEvent & event);
+  void OnCmdVectorSRIDs(wxCommandEvent & event);
+  void OnCmdVectorKeywords(wxCommandEvent & event);
+  void OnCmdUpdateVectorExtent(wxCommandEvent & event);
+  void OnCmdUpdateVectorExtentAll(wxCommandEvent & event);
   void OnCmdShow(wxCommandEvent & event);
   void OnCmdDrop(wxCommandEvent & event);
   void OnCmdRename(wxCommandEvent & event);
   void OnCmdSelect(wxCommandEvent & event);
+  void OnCmdSelectTiles(wxCommandEvent & event);
   void OnCmdRefresh(wxCommandEvent & event);
+  void OnRefreshDeferred(wxCommandEvent & event);
   void OnCmdRecover(wxCommandEvent & event);
   void OnCmdShowSql(wxCommandEvent & event);
   void OnCmdSpatialIndex(wxCommandEvent & event);
@@ -1502,13 +2039,15 @@ public:
   bool DropRenameAux1(MyObject * obj, class GeomColsList * geometries,
                       bool * autoincrement);
   void DropRenameAux2(MyObject * obj, GeomColsList * geometries,
-                      wxString & aliasTable, wxString & renameSql,
-                      wxString & dropSql, wxString & disableSpatialIdxSql,
+                      wxString & aliasTable, wxString & new_column,
+                      wxString & renameSql, wxString & dropSql,
+                      wxString & disableSpatialIdxSql,
                       wxString & dropSpatialIdxSql,
                       wxString & createSpatialIdxSql,
                       wxString & discardGeometrySql);
-  void DropRenameAux3(MyObject * obj, GeomColsList * geometries,
-                      class TblIndexList * index, wxString & addGeometrySql);
+  void DropRenameAux3(MyObject * obj, wxString & new_column,
+                      GeomColsList * geometries, class TblIndexList * index,
+                      wxString & addGeometrySql);
   void OnCmdDropColumn(wxCommandEvent & event);
   void OnCmdRenameColumn(wxCommandEvent & event);
   void OnCmdGisLayerAuth(wxCommandEvent & event);
@@ -1519,6 +2058,12 @@ public:
   void OnCmdDetachDB(wxCommandEvent & event);
   void OnCmdCheckGeometries(wxCommandEvent & event);
   void OnCmdSanitizeGeometries(wxCommandEvent & event);
+  void OnCmdSldSeRasterStyles(wxCommandEvent & event);
+  void OnCmdSldSeVectorStyles(wxCommandEvent & event);
+  void OnCreateRasterCoverage(wxCommandEvent & event);
+  void OnRegisterVectorCoverage(wxCommandEvent & event);
+  void OnItemCollapsed(wxTreeEvent & event);
+  void OnItemExpanding(wxTreeEvent & event);
 };
 
 class SqlThreadParams
@@ -1650,6 +2195,11 @@ public:
   {
     return AbortRequested;
   }
+  void Finalize()
+  {
+    sqlite3_finalize(Stmt);
+    Stmt = NULL;
+  }
 };
 
 class MyResultSetView:public wxPanel
@@ -1669,13 +2219,17 @@ private:
   int RsBeginRow;
   int RsEndRow;
   int RsMaxRow;
+  bool IsMaxAlreadySet;
   int CurrentEvtRow;
   int CurrentEvtColumn;
+  int CurrentTileId;
+  wxString TileDataTable;
   MyVariant *CurrentBlob;
   wxGrid *TableView;
   MyBlobs *TableBlobs;
   MyValues *TableValues;
   bool ReadOnly;
+  bool CoverageTiles;
   sqlite3_int64 *RowIds;
   int PrimaryKeys[1024];
   int BlobColumns[1024];
@@ -1685,6 +2239,8 @@ private:
   wxString SqlErrorMsg;
   SqlThreadParams ThreadParams;
   void XmlBlobOut(bool indented);
+  const char *CleanSqlTail(const char *dirty);
+  void UpdateMaxRow(wxString & sql);
 public:
     MyResultSetView()
   {;
@@ -1703,14 +2259,16 @@ public:
                  wxString & tableName);
   void CreateGrid(int rows, int cols);
   void CreateStatsGrid();
-  bool ExecuteSqlPre(wxString & sql, int from, bool read_only);
+  bool ExecuteSqlPre(wxString & sql, int from, bool read_only, bool coverage,
+                     wxString & tile_data_table, bool reset);
   bool ExecuteSqlPost(void);
   void AbortRequested(void);
   wxStaticText *GetCurrentBlock()
   {
     return RsCurrentBlock;
   }
-  void FormatElapsedTime(double seconds, char *elapsed, bool simple = false);
+  static void FormatElapsedTime(double seconds, char *elapsed, bool simple =
+                                false);
   int GetRsBlock()
   {
     return RsBlock;
@@ -1755,6 +2313,7 @@ public:
   void OnCmdExpDif(wxCommandEvent & event);
   void OnCmdExpSylk(wxCommandEvent & event);
   void OnCmdExpDbf(wxCommandEvent & event);
+  void OnCmdTilePreview(wxCommandEvent & event);
 };
 
 class MySqlControl:public wxTextCtrl
@@ -1825,6 +2384,7 @@ public:
   static bool IsSqlNumber(wxString & str);
   static bool IsSqlFunction(wxString & str, char next_c);
   static bool IsSqlGeoFunction(wxString & str, char next_c);
+  static bool IsSqlRasterFunction(wxString & str, char next_c);
   bool IsIgnoreEvent()
   {
     return IgnoreEvent;
@@ -1850,6 +2410,8 @@ public:
     return &History;
   }
   void SetSql(wxString & sql, bool execute);
+  void SetSql(wxString & sql, bool execute, bool coverage,
+              wxString & tile_data_table, bool reset);
   void SetHistoryStates();
   void OnSize(wxSizeEvent & event);
   void OnSqlGo(wxCommandEvent & event);
@@ -2086,7 +2648,7 @@ public:
   {
     return &ProgressCount;
   }
-  void SetLastProgressCount(int last)
+  void SetLastProgressCount()
   {
     LastProgressCount = 0;
   }
@@ -2170,6 +2732,10 @@ private:
   wxGauge *Progress;
   int CurrentEvtRow;
   int CurrentEvtColumn;
+  bool ProxyEnabled;
+  wxString WfsGetCapabilitiesURL;
+  wxString PreviousHttpProxy;
+  wxString HttpProxy;
   gaiaWFSitemPtr FindLayerByName(wxString & name);
   void SelectLayer();
 public:
@@ -2178,6 +2744,7 @@ public:
     Catalog = NULL;
     WfsView = NULL;
     Keywords = NULL;
+    ProxyEnabled = false;
     ProgressTimer = NULL;
   }
   virtual ~ WfsDialog()
@@ -2195,8 +2762,9 @@ public:
   void ResetProgress();
   void ProgressWait();
   void ProgressUpdate(int rows);
-  bool Create(MyFrame * parent);
+  bool Create(MyFrame * parent, wxString & wfs_url, wxString & proxy);
   void CreateControls();
+  void OnProxy(wxCommandEvent & event);
   void OnPagingChanged(wxCommandEvent & event);
   void OnLeftClick(wxGridEvent & event);
   void OnRightClick(wxGridEvent & event);
@@ -2300,24 +2868,92 @@ public:
   void OnCmdBlob(wxCommandEvent & event);
 };
 
-class DbStatusDialog:public wxDialog
+class TableViewItem
 {
 //
-// a dialog displaying DB Status infos
+// an ancillary class wrapping Tables and Views
 //
 private:
-  MyFrame * MainFrame;
-  wxGrid *GridCtrl;
-  wxStaticBitmap *Graph;
-  int CurrentEvtRow;
-  int CurrentEvtColumn;
-  int *DynamicIds;
-  int *DynamicModes;
-  wxTimer *RefreshTimer;
-  enum StatusModes
-  {
-    ModeNone,
-    ModeStatusBoth,
+  wxString Name;
+  bool View;
+  bool Virtual;
+  bool Geometry;
+  TableViewItem *Next;
+public:
+    TableViewItem(wxString & name, bool is_view, bool is_virtual);
+   ~TableViewItem()
+  {;
+  }
+  wxString & GetName()
+  {
+    return Name;
+  }
+  bool IsView()
+  {
+    return View;
+  }
+  bool IsVirtual()
+  {
+    return Virtual;
+  }
+  void SetGeometry()
+  {
+    Geometry = true;
+  }
+  bool IsGeometry()
+  {
+    return Geometry;
+  }
+  void SetNext(TableViewItem * next)
+  {
+    Next = next;
+  }
+  TableViewItem *GetNext()
+  {
+    return Next;
+  }
+};
+
+class TableViewList
+{
+//
+// an ancillary class used to build the Tree Control
+//
+private:
+  TableViewItem * First;
+  TableViewItem *Last;
+  int Count;
+  TableViewItem **Sorted;
+public:
+    TableViewList();
+   ~TableViewList();
+  void Add(wxString & name, bool isView, bool isVirtual);
+  void PrepareSorted();
+  void SetGeometry(wxString & name);
+  TableViewItem *GetFirst()
+  {
+    return First;
+  }
+};
+
+class DbStatusDialog:public wxDialog
+{
+//
+// a dialog displaying DB Status infos
+//
+private:
+  MyFrame * MainFrame;
+  wxGrid *GridCtrl;
+  wxStaticBitmap *Graph;
+  int CurrentEvtRow;
+  int CurrentEvtColumn;
+  int *DynamicIds;
+  int *DynamicModes;
+  wxTimer *RefreshTimer;
+  enum StatusModes
+  {
+    ModeNone,
+    ModeStatusBoth,
     ModeStatusFirst,
     ModeStatusSecond,
     ModeStatusBothBytes,
@@ -2346,13 +2982,36 @@ public:
   void OnRefreshTimer(wxTimerEvent & event);
 };
 
+class MyStatusBar:public wxStatusBar
+{
+//
+// a StatusBar with an Icon
+//
+private:
+  MyFrame * Parent;
+  wxStaticBitmap *Bitmap;
+public:
+    MyStatusBar(MyFrame * parent);
+    virtual ~ MyStatusBar()
+  {;
+  }
+  void SetSecurityRelaxedIcon();
+  void SetSecurityStrongIcon();
+  void SetReadOnlyIcon();
+  void SetNotConnectedIcon();
+  void SetText(wxString & msg);
+  void OnSize(wxSizeEvent & event);
+};
+
 class MyFrame:public wxFrame
 {
 //
 // the main GUI frame
 //
 private:
+  char *Old_SPATIALITE_SECURITY_ENV;
   wxString AutoFDOmsg;
+  wxString AutoGPKGmsg;
   bool SpatiaLiteMetadata;
   wxAuiManager Manager;         // the GUI manager
   wxString ConfigLayout;        // PERSISTENCY - the layout configuration
@@ -2360,15 +3019,20 @@ private:
   int ConfigPaneY;              // PERSISTENCY - the main pane screen origin Y
   int ConfigPaneWidth;          // PERSISTENCY - the main pane screen width
   int ConfigPaneHeight;         // PERSISTENCY - the main pane screen height
-  wxString ConfigDbPath;        // PERSISTENCY - the last opend DB path
-  wxString ConfigDir;           // PERSISTENCY -  the last used directory
+  wxString ConfigDbPath;        // PERSISTENCY - the last opened DB path
+  wxString ConfigDir;           // PERSISTENCY - the last used directory
+  wxString HttpProxy;           // PERSISTENCY - the last used HTTP Proxy
+  wxString WfsGetCapabilitiesURL; // PERSISTENCY - the last used WFS GetCapabilities URL
   MyTableTree *TableTree;       // the tables tree list
   MyQueryView *QueryView;       // the QueryResult panel
   MyResultSetView *RsView;      // the QueryResult panel
   bool HelpPane;                // is the HELP pane already opened ?
+  bool SecurityRelaxed;         // is "SPATIALITE_SECURITY=relaxed" currently set ?
+  int RL2MaxThreads;            // max concurrent threads for RL2
   sqlite3 *SqliteHandle;        // handle for SQLite DB
   wxString SqlitePath;          // path of SQLite DB
-  void *InternalCache;          // pointer to the InternalCache supporting the DB connection
+  void *SpliteInternalCache;    // pointer to the InternalCache supporting the DB connection
+  void *RL2PrivateData;         // pointer to RL2 Private Data
   wxString ExternalSqlitePath;  // path of external SQLite DB [LOAD/SAVE MEMORY database]
   bool MemoryDatabase;          // TRUE if we are currently working on the MEMORY database
   wxString LastDirectory;       // path of directory used  
@@ -2382,6 +3046,7 @@ private:
   wxString *TableNames;         // array of tables
   wxBitmap *BtnCreateNew;       // button icon for DB CREATE&CONNECT
   wxBitmap *BtnConnect;         // button icon for DB CONNECT
+  wxBitmap *BtnConnectReadOnly; // button icon for DB CONNECT - READ ONLY
   wxBitmap *BtnDisconnect;      // button icon for DB DISCONNECT
   wxBitmap *BtnMemDbLoad;       // button icon for MEMORY DB LOAD
   wxBitmap *BtnMemDbNew;        // button icon for MEMORY DB NEW
@@ -2413,6 +3078,7 @@ private:
   wxBitmap *BtnSaneGeom;        // button icon for SaneGeom
   wxBitmap *BtnWFS;             // button icon for WFS
   wxBitmap *BtnDXF;             // button icon for DXF
+  bool ReadOnlyConnection;
 // AutoSave timer
   int AutoSaveInterval;
   int LastTotalChanges;
@@ -2424,11 +3090,23 @@ private:
   bool SqlLogEnabled;
   bool GetLwGeomVersion(char *buf);
   bool GetLibXml2Version(char *buf);
+  MyStatusBar *StatusBar;
+  void TestSecurityRelaxed(const char *path);
+  bool IsSafeDB(const char *path);
+  void SetSecurityRelaxed();
+  void ResetSecurity();
+  rl2PixelPtr DefaultNoData(unsigned char sample, unsigned char pixel,
+                            unsigned char num_bands);
+  rl2PixelPtr ParseNoData(wxString & NoData, int SampleType, int PixelType,
+                          int NumBands);
+  char *GetNum(const char *start, const char *end);
+  bool IsValidSqliteFile(wxString & path);
+  void DoUpdateRL2MaxThreads();
 public:
     MyFrame(const wxString & title, const wxPoint & pos, const wxSize & size);
     virtual ~ MyFrame();
 
-  void UpdateStatusBar();
+  void UpdateStatusBar(bool changeIcon = true);
   bool IsConnected()
   {
     if (SqliteHandle)
@@ -2436,6 +3114,11 @@ public:
     else
       return false;
   }
+  bool IsSecurityLevelRelaxed()
+  {
+    return SecurityRelaxed;
+  }
+  int GetRL2MaxThreads();
 
   static void DoubleQuotedSql(char *str);
   static void CleanSqlString(char *sql);
@@ -2479,9 +3162,18 @@ public:
   {
     return SqliteHandle;
   }
-  void *GetInternalCache()
+  void *GetSpliteInternalCache()
   {
-    return InternalCache;
+    return SpliteInternalCache;
+  }
+  int GetDecimalPrecision();
+  void *GetRL2PrivateData()
+  {
+    return RL2PrivateData;
+  }
+  bool IsSecurityRelaxed()
+  {
+    return SecurityRelaxed;
   }
   void CloseHelpPane()
   {
@@ -2492,12 +3184,14 @@ public:
     HelpPane = true;
   }
 
-  bool OpenDB();
+  bool OpenDB(bool read_only);
   bool CreateDB();
   void CloseDB();
   void InitializeSpatialMetadata();
   void AutoFDOStart();
   void AutoFDOStop();
+  void AutoGPKGStart();
+  void AutoGPKGStop();
   void InitTableTree();
   void LoadHistory();
   bool HasHistory();
@@ -2509,11 +3203,15 @@ public:
   bool HasVirtsMetadata();
   bool HasViewsMetadata(wxString & dbAlias);
   bool HasVirtsMetadata(wxString & dbAlias);
+  void FindGeometries(TableViewList * list);
+  void FindGeometries(wxString & dbAlias, TableViewList * list);
+
   void GetTableColumns(wxString & tableName, MyTableInfo * list);
   void GetTableIndices(wxString & tableName, MyTableInfo * list);
   void GetTableTriggers(wxString & tableName, MyTableInfo * list);
   void GetViewColumns(wxString & viewName, MyViewInfo * list);
   void GetViewTriggers(wxString & viewName, MyViewInfo * list);
+  void CheckGPKG(wxString & tableName, MyTableInfo * list);
   void GetIndexFields(wxString & indexName, wxTreeItemId & node);
   void GetPrimaryKeyFields(wxString & indexName, wxTreeItemId & node);
   void GetForeignKeys(wxString & tableName, wxTreeItemId & node);
@@ -2537,6 +3235,10 @@ public:
   bool ExistsTopologyMaster(wxString & dbAlias);
   void GetTopologyColumns(wxString * list);
   void GetTopologyColumns(wxString & dbAlias, wxString * list);
+  bool ExistsRasterCoverages();
+  bool ExistsRasterCoverages(wxString & dbAlias);
+  bool ExistsVectorCoverages();
+  bool ExistsVectorCoverages(wxString & dbAlias);
   void CheckIfExists(const char *name, bool * table, bool * view);
   void CheckIfExists(wxString & dbAlias, const char *name, bool * table,
                      bool * view);
@@ -2559,9 +3261,16 @@ public:
   {
     QueryView->SetSql(sql, execute);
   }
+  void SetSql(wxString & sql, bool execute, bool coverage,
+              wxString & tile_data_table, bool reset)
+  {
+    QueryView->SetSql(sql, execute, coverage, tile_data_table, reset);
+  }
   bool ExecuteSql(const char *sql, int rowNo);
   void Rollback();
+  void DoCreateStylingTables(void);
   bool TableAlreadyExists(wxString & name);
+  bool CoverageAlreadyExists(wxString & name);
   bool SridNotExists(int srid);
   bool CheckMetadata();
   bool CheckMetadata(wxString & dbAlias);
@@ -2579,7 +3288,7 @@ public:
   {
     return CharsetsLen;
   }
-  gaiaDbfFieldPtr GetDbfField(gaiaDbfListPtr list, char *name);
+  gaiaDbfFieldPtr GetDbfField(gaiaDbfListPtr list, int index);
   void OutputPrjFile(wxString & path, int srid);
   void LoadText(wxString & path, wxString & table, wxString & charset,
                 bool first_titles, const char decimal_separator,
@@ -2621,6 +3330,22 @@ public:
   {
     return LastDirectory;
   }
+  void SetHttpProxy(wxString & proxy)
+  {
+    HttpProxy = proxy;
+  }
+  wxString & GetHttpProxy()
+  {
+    return HttpProxy;
+  }
+  void SetWfsGetCapabilitiesURL(wxString & url)
+  {
+    WfsGetCapabilitiesURL = url;
+  }
+  wxString & GetWfsGetCapabilitiesURL()
+  {
+    return WfsGetCapabilitiesURL;
+  }
   wxString & GetLocaleCharset()
   {
     return LocaleCharset;
@@ -2646,13 +3371,23 @@ public:
   }
   wxString *GetTables(int *cnt);
   void BuildNetwork(wxString & table, wxString & from, wxString & to,
-                    wxString & geometry, wxString & name, bool cost_length,
-                    wxString & cost, bool bidirectional, bool one_way,
-                    wxString & one_way_from_to, wxString & one_way_to_from,
-                    bool aStarSupported);
+                    bool isNoGeometry, wxString & geometry, wxString & name,
+                    bool cost_length, wxString & cost, bool bidirectional,
+                    bool one_way, wxString & one_way_from_to,
+                    wxString & one_way_to_from, bool aStarSupported,
+                    wxString & dataTableName, wxString & virtualTableName);
+  void BuildNetwork(wxString & table, wxString & from, wxString & to,
+                    wxString & name, wxString & cost, bool bidirectional,
+                    bool one_way, wxString & one_way_from_to,
+                    wxString & one_way_to_from, wxString & dataTableName,
+                    wxString & virtualTableName);
   bool CreateNetwork(class Network * net, wxString & table, wxString & from,
                      wxString & to, wxString & geometry, wxString & name,
-                     bool aStarSupported, double aStarCoeff);
+                     bool aStarSupported, double aStarCoeff,
+                     wxString & dataTableName, wxString & virtualTableName);
+  bool CreateNetwork(class Network * net, wxString & table, wxString & from,
+                     wxString & to, wxString & name, wxString & dataTableName,
+                     wxString & virtualTableName);
   void ImportExifPhotos(wxString & path, bool folder, bool metadata,
                         bool gps_only);
   void ImportXmlDocuments(wxString & path, bool folder, wxString & suffix,
@@ -2726,6 +3461,11 @@ public:
   bool IsPrimaryKey(wxString & table, wxString & column);
   void DbPagesCount(int *total, int *frees);
 
+  void EnableAllTools(bool mode = true);
+  void DisableAllTools()
+  {
+    EnableAllTools(false);
+  };
 
   int TestDotCommand(const char *stmt);
   bool IsDotCommandLoadShp(const char *stmt, char *path, char *table,
@@ -2738,10 +3478,64 @@ public:
   bool IsDotCommandDumpShp(const char *stmt, char *table,
                            char *column, char *path, char *charset, char *type);
   bool IsViewGeometry(wxString & table, wxString & column);
+  bool GetTilePreview(wxString & currentTileData, int currentTileId,
+                      unsigned char **blob, int *blobSize);
+  class RasterCoverageStylesList *FindRasterCoverageStyles(wxString & coverage);
+  class RasterCoverageStylesList *FindRasterStyles();
+  class VectorCoverageStylesList *FindVectorCoverageStyles(wxString & coverage);
+  class VectorCoverageStylesList *FindVectorStyles();
+  class CandidateVectorCoveragesList *FindUnregisteredVectorCoverages();
+  bool DoRegisterVectorCoverage(wxString & name, wxString & table,
+                                wxString & geometry, wxString & title,
+                                wxString & abstract);
+  bool ValidateRasterStyle(const char *path, void **blob, int *blob_size);
+  bool ValidateRasterStyle(void **blob, int *blob_size, const char *xml);
+  bool DoInsertRasterSymbolizer(char *xml);
+  bool ValidateVectorStyle(const char *path, void **blob, int *blob_size);
+  bool ValidateVectorStyle(void **blob, int *blob_size, const char *xml);
+  bool DoInsertVectorSymbolizer(char *xml);
+  bool ValidateExternalGraphicResource(const char *path, void **blob,
+                                       int *blob_size, wxString & abstract);
+  class RasterCoverageSRIDsList *FindRasterAlternativeSRIDs(wxString &
+                                                            coverage);
+  class VectorCoverageSRIDsList *FindVectorAlternativeSRIDs(wxString &
+                                                            coverage);
+  class RasterCoverageKeywordsList *FindRasterKeywords(wxString & coverage);
+  class VectorCoverageKeywordsList *FindVectorKeywords(wxString & coverage);
+  class ExternalGraphicList *FindExternalGraphic(bool no_svg);
+  class TextFontList *FindTextFont(void);
+
+  bool GetCurrentlySelectedTable(wxString & table_name)
+  {
+    return TableTree->GetCurrentlySelectedTable(table_name);
+  }
+  bool DoGetRasterCoverageInfos(wxString & coverage, wxString & title,
+                                wxString & abstract, wxString & sample,
+                                wxString & pixel, wxString & compression,
+                                int *srid);
+  bool DoImportRasterFiles(wxString & coverage, wxString & title,
+                           wxArrayString & paths, int forced_srid,
+                           bool with_worldfile, bool pyramidize);
+  bool DoImportRaster(sqlite3_stmt * stmt, wxString & coverage, wxString & path,
+                      int forced_srid, bool with_worldfile, bool pyramidize);
+  bool DoGetVectorCoverageInfos(wxString & coverage, wxString & title,
+                                wxString & abstract, wxString & type,
+                                int *srid);
+  bool CreateRasterCoverage(wxString & CoverageName, wxString & Title,
+                            wxString & Abstract, int SampleType, int PixelType,
+                            int NumBands, int Compression, int Quality,
+                            int TileWidth, int TileHeight,
+                            bool NotGeoreferenced, int Srid,
+                            double HorzResolution, double VertResolution,
+                            wxString NoData, bool StrictResolution,
+                            bool MixedResolutions, bool InputPaths, bool MD5,
+                            bool Summary, int RedBand, int GreenBand,
+                            int BlueBand, int NIRband, bool AutoNDVI);
 
   void OnQuit(wxCommandEvent & event);
   void OnAbout(wxCommandEvent & event);
   void OnConnect(wxCommandEvent & event);
+  void OnConnectReadOnly(wxCommandEvent & event);
   void OnCreateNew(wxCommandEvent & event);
   void OnDisconnect(wxCommandEvent & event);
   void OnMemoryDbLoad(wxCommandEvent & event);
@@ -2797,6 +3591,7 @@ public:
   {;
   }
   void CreateControls();
+  void OnCancel(wxCommandEvent & event);
   void OnClose(wxCloseEvent & event);
   void OnSize(wxSizeEvent & event);
 };
@@ -3395,14 +4190,15 @@ private:
   wxString Geometry;            // the geometry column's name 
   bool ReadOnly;
   bool Hidden;
+  bool IsTable;
 public:
     GisLayerAuthDialog()
   {;
   }
   GisLayerAuthDialog(MyFrame * parent, wxString & table, wxString & geom,
-                     bool rdOnly, bool hidden);
+                     bool rdOnly, bool hidden, bool is_table);
   bool Create(MyFrame * parent, wxString & table, wxString & geom, bool rdOnly,
-              bool hidden);
+              bool hidden, bool is_table);
   virtual ~ GisLayerAuthDialog()
   {;
   }
@@ -3432,6 +4228,7 @@ private:
   wxString Default;             // the default charset
   wxString Charset;             // the SHP charset
   int Srid;                     // the SRID
+  bool TextDates;
 public:
     VirtualShpDialog()
   {;
@@ -3456,7 +4253,12 @@ public:
   {
     return Srid;
   }
+  bool IsTextDates()
+  {
+    return TextDates;
+  }
   void OnOk(wxCommandEvent & event);
+  void OnTextDates(wxCommandEvent & event);
 };
 
 class VirtualTxtDialog:public wxDialog
@@ -3527,6 +4329,7 @@ private:
   wxString Table;               // the table name
   wxString Default;             // the default charset
   wxString Charset;             // the DBF charset
+  bool TextDates;
 public:
     VirtualDbfDialog()
   {;
@@ -3547,7 +4350,12 @@ public:
   {
     return Charset;
   }
+  bool IsTextDates()
+  {
+    return TextDates;
+  }
   void OnOk(wxCommandEvent & event);
+  void OnTextDates(wxCommandEvent & event);
 };
 
 class LoadShpDialog:public wxDialog
@@ -3573,6 +4381,7 @@ private:
   int PKCount;                  // # Primary Key Columns
   wxString *PKFields;           // array of Primary Key Columns
   wxString *PKFieldsEx;         // array of Primary Key Columns (full detail)
+  bool TextDates;
 public:
     LoadShpDialog()
   {;
@@ -3627,10 +4436,15 @@ public:
   {
     return PKColumn;
   }
+  bool IsTextDates()
+  {
+    return TextDates;
+  }
   void LoadPKFields();
   void OnOk(wxCommandEvent & event);
   void OnUserGType(wxCommandEvent & event);
   void OnUserPKey(wxCommandEvent & event);
+  void OnTextDates(wxCommandEvent & event);
 };
 
 class DumpPostGISDialog:public wxDialog
@@ -3894,6 +4708,7 @@ private:
   int PKCount;                  // # Primary Key Columns
   wxString *PKFields;           // array of Primary Key Columns
   wxString *PKFieldsEx;         // array of Primary Key Columns (full detail)
+  bool TextDates;
 public:
     LoadDbfDialog()
   {;
@@ -3920,9 +4735,14 @@ public:
   {
     return PKColumn;
   }
+  bool IsTextDates()
+  {
+    return TextDates;
+  }
   void LoadPKFields();
   void OnOk(wxCommandEvent & event);
   void OnUserPKey(wxCommandEvent & event);
+  void OnTextDates(wxCommandEvent & event);
 };
 
 class NetworkDialog:public wxDialog
@@ -3935,6 +4755,7 @@ private:
   wxString TableName;           // the table name
   wxString FromColumn;          // the NodeFrom column name
   wxString ToColumn;            // the NodeTo column name
+  bool NoGeometry;              // no Geometry column
   wxString GeomColumn;          // the Geometry column name
   bool GeomLength;              // Cost is Geometry Length
   wxString CostColumn;          // the Cost column name
@@ -3945,6 +4766,8 @@ private:
   bool NameEnabled;             // Name column supported
   wxString NameColumn;          // the Name column name
   bool AStarSupported;          // A* algorithm supported
+  wxString DataTable;           // name of the binary data table
+  wxString VirtualTable;        // name of the VirtualNetwork table
 public:
     NetworkDialog()
   {;
@@ -3967,6 +4790,10 @@ public:
   {
     return ToColumn;
   }
+  bool IsNoGeometry()
+  {
+    return NoGeometry;
+  }
   wxString & GetGeomColumn()
   {
     return GeomColumn;
@@ -4007,11 +4834,20 @@ public:
   {
     return AStarSupported;
   }
+  wxString & GetDataTable()
+  {
+    return DataTable;
+  }
+  wxString & GetVirtualTable()
+  {
+    return VirtualTable;
+  }
   void OnTable(wxCommandEvent & event);
   void OnDirection(wxCommandEvent & event);
   void OnCost(wxCommandEvent & event);
   void OnOneWay(wxCommandEvent & event);
   void OnNameEnabled(wxCommandEvent & event);
+  void OnNoGeometry(wxCommandEvent & event);
   void OnOk(wxCommandEvent & event);
 };
 
@@ -4254,6 +5090,171 @@ public:
   void OnOk(wxCommandEvent & event);
 };
 
+class CreateRasterCoverageDialog:public wxDialog
+{
+//
+// a dialog preparing an IMPORT DXF FILE(s)
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  wxString Title;
+  wxString Abstract;
+  int SampleType;
+  int PixelType;
+  int NumBands;
+  int RedBand;
+  int GreenBand;
+  int BlueBand;
+  int NIRband;
+  bool AutoNDVI;
+  int Compression;
+  int Quality;
+  int TileWidth;
+  int TileHeight;
+  bool NotGeoreferenced;
+  int Srid;
+  double HorzResolution;
+  double VertResolution;
+  wxString NoData;
+  bool StrictResolution;
+  bool MixedResolutions;
+  bool InputPaths;
+  bool MD5;
+  bool Summary;
+  bool IsValidNoData(wxString & no_data, int sample, int num_bands);
+public:
+    CreateRasterCoverageDialog()
+  {;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ CreateRasterCoverageDialog()
+  {;
+  }
+  void CreateControls();
+  wxString & GetCoverageName()
+  {
+    return CoverageName;
+  }
+  wxString & GetTitle()
+  {
+    return Title;
+  }
+  wxString & GetAbstract()
+  {
+    return Abstract;
+  }
+  int GetSampleType()
+  {
+    return SampleType;
+  }
+  int GetPixelType()
+  {
+    return PixelType;
+  }
+  int GetNumBands()
+  {
+    return NumBands;
+  }
+  int GetRedBand()
+  {
+    return RedBand;
+  }
+  int GetGreenBand()
+  {
+    return GreenBand;
+  }
+  int GetBlueBand()
+  {
+    return BlueBand;
+  }
+  int GetNIRband()
+  {
+    return NIRband;
+  }
+  bool IsAutoNDVI()
+  {
+    return AutoNDVI;
+  }
+  int GetCompression()
+  {
+    return Compression;
+  }
+  int GetQuality()
+  {
+    return Quality;
+  }
+  int GetTileWidth()
+  {
+    return TileWidth;
+  }
+  int GetTileHeight()
+  {
+    return TileHeight;
+  }
+  bool IsNotGeoreferenced()
+  {
+    return NotGeoreferenced;
+  }
+  int GetSrid()
+  {
+    return Srid;
+  }
+  double GetHorzResolution()
+  {
+    return HorzResolution;
+  }
+  double GetVertResolution()
+  {
+    return VertResolution;
+  }
+  wxString & GetNoData()
+  {
+    return NoData;
+  }
+  bool IsStrictResolution()
+  {
+    return StrictResolution;
+  }
+  bool IsMixedResolutions()
+  {
+    return MixedResolutions;
+  }
+  bool IsInputPaths()
+  {
+    return InputPaths;
+  }
+  bool IsMD5()
+  {
+    return MD5;
+  }
+  bool IsSummary()
+  {
+    return Summary;
+  }
+  void OnSampleChanged(wxCommandEvent & event);
+  void OnPixelChanged(wxCommandEvent & event);
+  void OnCompressionChanged(wxCommandEvent & event);
+  void OnNumBandsChanged(wxCommandEvent & event);
+  void OnRedBandChanged(wxCommandEvent & event);
+  void OnGreenBandChanged(wxCommandEvent & event);
+  void OnBlueBandChanged(wxCommandEvent & event);
+  void OnNIRbandChanged(wxCommandEvent & event);
+  void OnAutoNDVIchanged(wxCommandEvent & event);
+  void OnSquareTileChanged(wxCommandEvent & event);
+  void OnNoGeorefChanged(wxCommandEvent & event);
+  void OnSameResChanged(wxCommandEvent & event);
+  void OnTileWidthChanged(wxCommandEvent & event);
+  void OnTileHeightChanged(wxCommandEvent & event);
+  void OnHorzResChanged(wxCommandEvent & event);
+  void OnStrictChanged(wxCommandEvent & event);
+  void OnMixedChanged(wxCommandEvent & event);
+  void OnPathsChanged(wxCommandEvent & event);
+  void OnMD5Changed(wxCommandEvent & event);
+  void OnSummaryChanged(wxCommandEvent & event);
+  void OnOk(wxCommandEvent & event);
+};
+
 class SqlScriptDialog:public wxDialog
 {
 //
@@ -4321,6 +5322,11 @@ private:
   int BlobSize;                 // the BLOB size
   unsigned char *Blob;          // the BLOB value
   int BlobType;                 // the BLOB type
+  bool IsTextFont;
+  wxString FontFamily;
+  wxString FontStyle;
+  bool IsFontBold;
+  bool IsFontItalic;
   bool IsSVG;
   double SvgWidth;
   double SvgHeight;
@@ -4412,6 +5418,35 @@ public:
   void OnCopyXmlIndented(wxCommandEvent & event);
 };
 
+class TilePreviewDialog:public wxDialog
+{
+//
+// a dialog to show a Raster Tile Preview
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageTable;
+  int TileId;
+  wxImage *Image;               // the image
+  bool Painted;
+public:
+    TilePreviewDialog()
+  {;
+  }
+  TilePreviewDialog(MyFrame * parent, wxString & coverage, int tile_id,
+                    int blob_size, unsigned char *blob);
+  bool Create(MyFrame * parent, wxString & coverage, int tile_id, int blob_size,
+              unsigned char *blob);
+  virtual ~ TilePreviewDialog()
+  {
+    if (Image)
+      delete Image;
+  }
+  void CreateControls();
+  void OnPaint(wxPaintEvent & event);
+  void OnOk(wxCommandEvent & event);
+};
+
 class GraphicsGeometry:public wxStaticBitmap
 {
 //
@@ -4663,6 +5698,8 @@ public:
   void AddNode(wxString & code);
   NetNode *ProcessNode(sqlite3_int64 id, double x, double y, NetNode ** pOther);
   NetNode *ProcessNode(wxString & code, double x, double y, NetNode ** pOther);
+  NetNode *ProcessNode(sqlite3_int64 id, NetNode ** pOther);
+  NetNode *ProcessNode(wxString & code, NetNode ** pOther);
   void Sort();
   NetNode *Find(sqlite3_int64 id);
   NetNode *Find(wxString & code);
@@ -4673,6 +5710,10 @@ public:
   void AddArc(sqlite3_int64 rowid, const char *code_from, const char *code_to,
               double node_from_x, double node_from_y, double node_to_x,
               double node_to_y, double cost);
+  void AddArc(sqlite3_int64 rowid, sqlite3_int64 id_from, sqlite3_int64 id_to,
+              double cost);
+  void AddArc(sqlite3_int64 rowid, const char *code_from, const char *code_to,
+              double cost);
   void InitNodes();
   void SetError()
   {
@@ -4708,7 +5749,7 @@ private:
 public:
     AutoFDOTable(const char *name, const int len)
   {
-    Name = new char[len+1];
+    Name = new char[len + 1];
       strcpy(Name, name);
       Next = NULL;
   }
@@ -4750,6 +5791,56 @@ public:
   }
 };
 
+class AutoGPKGTable
+{
+private:
+  char *Name;
+  AutoGPKGTable *Next;
+public:
+    AutoGPKGTable(const char *name, const int len)
+  {
+    Name = new char[len + 1];
+      strcpy(Name, name);
+      Next = NULL;
+  }
+   ~AutoGPKGTable()
+  {
+    if (Name)
+      delete[]Name;
+  }
+  char *GetName()
+  {
+    return Name;
+  }
+  void SetNext(AutoGPKGTable * next)
+  {
+    Next = next;
+  }
+  AutoGPKGTable *GetNext()
+  {
+    return Next;
+  }
+};
+
+class AutoGPKGTables
+{
+private:
+  AutoGPKGTable * First;
+  AutoGPKGTable *Last;
+public:
+    AutoGPKGTables()
+  {
+    First = NULL;
+    Last = NULL;
+  }
+   ~AutoGPKGTables();
+  void Add(const char *name, const int len);
+  AutoGPKGTable *GetFirst()
+  {
+    return First;
+  }
+};
+
 class AutoSaveDialog:public wxDialog
 {
 //
@@ -5029,35 +6120,2829 @@ public:
   void OnOk(wxCommandEvent & event);
 };
 
-class ComposerMainPage:public wxPanel
+class RasterCoverageStyle
 {
-//
-// first page used by Query/View COMPOSER
-//
+// an SLD/SE Raster style
 private:
-  class ComposerDialog * Parent;
-  wxCheckBox *Table2Ctrl;
-  wxComboBox *Table1NameCtrl;
-  wxComboBox *Table2NameCtrl;
-  wxTextCtrl *Table1AliasCtrl;
-  wxTextCtrl *Table2AliasCtrl;
-  wxListBox *Table1ColumnsCtrl;
-  wxListBox *Table2ColumnsCtrl;
-  wxRadioBox *JoinModeCtrl;
-  wxCheckBox *Match2Ctrl;
-  wxCheckBox *Match3Ctrl;
-  wxComboBox *Match1Table1Ctrl;
-  wxComboBox *Match1Table2Ctrl;
-  wxComboBox *Match2Table1Ctrl;
-  wxComboBox *Match2Table2Ctrl;
-  wxComboBox *Match3Table1Ctrl;
-  wxComboBox *Match3Table2Ctrl;
+  int StyleID;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  wxString SchemaValidated;
+  wxString SchemaURI;
+  bool Selected;
+  RasterCoverageStyle *Next;
 public:
-    ComposerMainPage()
+    RasterCoverageStyle(int style_id, wxString & name, wxString & title,
+                        wxString & abstract, wxString & validated,
+                        wxString & schema_uri);
+   ~RasterCoverageStyle()
   {;
   }
-  bool Create(ComposerDialog * parent);
-  virtual ~ ComposerMainPage()
+  int GetStyleID()
+  {
+    return StyleID;
+  }
+  wxString & GetName()
+  {
+    return Name;
+  }
+  wxString & GetTitle()
+  {
+    return Title;
+  }
+  wxString & GetAbstract()
+  {
+    return Abstract;
+  }
+  wxString & GetSchemaValidated()
+  {
+    return SchemaValidated;
+  }
+  wxString & GetSchemaURI()
+  {
+    return SchemaURI;
+  }
+  void MarkSelected()
+  {
+    Selected = true;
+  }
+  bool IsSelected()
+  {
+    return Selected;
+  }
+  RasterCoverageStyle *GetNext()
+  {
+    return Next;
+  }
+  void SetNext(RasterCoverageStyle * next)
+  {
+    Next = next;
+  }
+};
+
+class RasterCoverageStylesList
+{
+// a container for Raster Coverage SLD/SE styles
+private:
+  RasterCoverageStyle * First;
+  RasterCoverageStyle *Last;
+public:
+    RasterCoverageStylesList();
+   ~RasterCoverageStylesList();
+  void Add(int style_id, wxString & name, wxString & title, wxString & abstract,
+           wxString & validated, wxString & schema_uri);
+  void MarkSelected(int stileId);
+  RasterCoverageStyle *GetFirst()
+  {
+    return First;
+  }
+};
+
+class RasterLoadParams
+{
+// a class wrapping Raster Import arguments
+private:
+  MyFrame * MainFrame;
+  class ImportRasterDialog *Dlg;
+  wxString CoverageName;
+  wxArrayString Paths;
+  wxString CurrentPath;
+  int Srid;
+  bool WithWorldFile;
+  bool Pyramidize;
+  bool Error;
+  int Count;
+  bool AbortPending;
+public:
+    RasterLoadParams()
+  {;
+  }
+   ~RasterLoadParams()
+  {;
+  }
+  void Initialize(MyFrame * mother, ImportRasterDialog * dlg,
+                  wxString & coverage, wxArrayString & paths, int srid,
+                  bool with_worldfile, bool pyramidize)
+  {
+    MainFrame = mother;
+    Dlg = dlg;
+    CoverageName = coverage;
+    Paths = paths;
+    Srid = srid;
+    WithWorldFile = with_worldfile;
+    Pyramidize = pyramidize;
+    Error = false;
+    Count = 0;
+    AbortPending = false;
+  }
+  MyFrame *GetMainFrame()
+  {
+    return MainFrame;
+  }
+  ImportRasterDialog *GetDlg()
+  {
+    return Dlg;
+  }
+  wxString & GetCoverageName()
+  {
+    return CoverageName;
+  }
+  int GetPathsCount()
+  {
+    return Paths.Count();
+  }
+  wxString & GetPathByIndex(int idx)
+  {
+    return Paths.Item(idx);
+  }
+  int GetSrid()
+  {
+    return Srid;
+  }
+  bool IsWithWorldFile()
+  {
+    return WithWorldFile;
+  }
+  bool IsPyramidize()
+  {
+    return Pyramidize;
+  }
+  void SetCurrentPath(wxString & path)
+  {
+    CurrentPath = path;
+  }
+  wxString & GetCurrentPath()
+  {
+    return CurrentPath;
+  }
+  void SetError()
+  {
+    Error = true;
+  }
+  bool GetError()
+  {
+    return Error;
+  }
+  void Done()
+  {
+    Count++;
+  }
+  int GetCount()
+  {
+    return Count;
+  }
+  void RequestAbort()
+  {
+    AbortPending = true;
+  }
+  bool IsAbortPending()
+  {
+    return AbortPending;
+  }
+};
+
+class ImportRasterDialog:public wxDialog
+{
+//
+// a dialog for importing external Raster files into a Coverage
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  wxArrayString Paths;
+  wxString Path;
+  wxString Title;
+  wxString Abstract;
+  wxString Sample;
+  wxString Pixel;
+  wxString Compression;
+  bool ForceSrid;
+  int Srid;
+  bool WithWorldFile;
+  bool Pyramidize;
+  wxString ListDone;
+  RasterLoadParams Params;
+public:
+    ImportRasterDialog()
+  {;
+  }
+  bool Create(MyFrame * parent, wxString & coverage, wxArrayString & paths,
+              wxString & path, wxString & title, wxString & abstract,
+              wxString & sample, wxString & pixel, wxString & compression,
+              int srid);
+  virtual ~ ImportRasterDialog()
+  {;
+  }
+  void CreateControls();
+  void DoRunLoad(void);
+  void OnCancel(wxCommandEvent & event);
+  void OnOk(wxCommandEvent & event);
+  void OnCmdAbort(wxCommandEvent & event);
+  void OnCmdForceSridChanged(wxCommandEvent & event);
+  void OnRequestStart(wxCommandEvent & event);
+  void OnRequestStop(wxCommandEvent & event);
+  void OnThreadFinished(wxCommandEvent & event);
+};
+
+class PyramidizeDialog:public wxDialog
+{
+//
+// a dialog supporting Pyramidize
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  wxString Title;
+  wxString Abstract;
+  wxString Sample;
+  wxString Pixel;
+  wxString Compression;
+public:
+    PyramidizeDialog()
+  {;
+  }
+  bool Create(MyFrame * parent, wxString & coverage, wxString & title,
+              wxString & abstract, wxString & sample, wxString & pixel,
+              wxString & compression);
+  virtual ~ PyramidizeDialog()
+  {;
+  }
+  void CreateControls();
+  bool DoPyramidize(void);
+  void OnOk(wxCommandEvent & event);
+};
+
+class PyramidizeMonolithicDialog:public wxDialog
+{
+//
+// a dialog supporting PyramidizeMonolithic
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  wxString Title;
+  wxString Abstract;
+  wxString Sample;
+  wxString Pixel;
+  wxString Compression;
+public:
+    PyramidizeMonolithicDialog()
+  {;
+  }
+  bool Create(MyFrame * parent, wxString & coverage, wxString & title,
+              wxString & abstract, wxString & sample, wxString & pixel,
+              wxString & compression);
+  virtual ~ PyramidizeMonolithicDialog()
+  {;
+  }
+  void CreateControls();
+  bool DoPyramidizeMonolithic(void);
+  void OnOk(wxCommandEvent & event);
+};
+
+class DePyramidizeDialog:public wxDialog
+{
+//
+// a dialog supporting DePyramidize
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  wxString Title;
+  wxString Abstract;
+  wxString Sample;
+  wxString Pixel;
+  wxString Compression;
+public:
+    DePyramidizeDialog()
+  {;
+  }
+  bool Create(MyFrame * parent, wxString & coverage, wxString & title,
+              wxString & abstract, wxString & sample, wxString & pixel,
+              wxString & compression);
+  virtual ~ DePyramidizeDialog()
+  {;
+  }
+  void CreateControls();
+  bool DoDePyramidize(void);
+  void OnOk(wxCommandEvent & event);
+};
+
+class RasterDropDialog:public wxDialog
+{
+//
+// a dialog supporting Drop Raster
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  wxString Title;
+  wxString Abstract;
+  wxString Sample;
+  wxString Pixel;
+  wxString Compression;
+public:
+    RasterDropDialog()
+  {;
+  }
+  bool Create(MyFrame * parent, wxString & coverage, wxString & title,
+              wxString & abstract, wxString & sample, wxString & pixel,
+              wxString & compression);
+  virtual ~ RasterDropDialog()
+  {;
+  }
+  void CreateControls();
+  bool DoDropCoverage(void);
+  void OnOk(wxCommandEvent & event);
+};
+
+class RasterCoverageStylesDialog:public wxDialog
+{
+//
+// a dialog for handling SLD/SE Raster Coverage's Styles
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  int CurrentRow;
+  int CurrentStyleID;
+  RasterCoverageStylesList *List;
+  wxGrid *GridCtrl;
+public:
+    RasterCoverageStylesDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent, wxString & coverage);
+  virtual ~ RasterCoverageStylesDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  void DoRegistetRasterCoverageStyles(class ListRasterStylesDialog * dlg);
+  void OnRightClick(wxGridEvent & event);
+  void OnCmdRemoveStyle(wxCommandEvent & event);
+  void OnAddStyle(wxCommandEvent & event);
+  void OnQuit(wxCommandEvent & event);
+};
+
+class ListRasterStylesDialog:public wxDialog
+{
+//
+// a dialog for listing and selecting SLD/SE Raster Styles
+//
+private:
+  MyFrame * MainFrame;
+  RasterCoverageStylesList *List;
+  wxGrid *GridCtrl;
+public:
+    ListRasterStylesDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ ListRasterStylesDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  int GetSelectedCount();
+  int GetSelectedStyleId(int idx);
+  void OnOk(wxCommandEvent & event);
+};
+
+class RasterStylesLoadParams
+{
+// a class wrapping Raster Styles Import arguments
+private:
+  MyFrame * MainFrame;
+  class LoadRasterStyleDialog *Dlg;
+  wxArrayString Paths;
+  wxString CurrentPath;
+  bool Error;
+  int Count;
+  bool AbortPending;
+public:
+    RasterStylesLoadParams()
+  {;
+  }
+   ~RasterStylesLoadParams()
+  {;
+  }
+  void Initialize(MyFrame * mother, LoadRasterStyleDialog * dlg,
+                  wxArrayString & paths)
+  {
+    MainFrame = mother;
+    Dlg = dlg;
+    Paths = paths;
+    Error = false;
+    Count = 0;
+    AbortPending = false;
+  }
+  MyFrame *GetMainFrame()
+  {
+    return MainFrame;
+  }
+  LoadRasterStyleDialog *GetDlg()
+  {
+    return Dlg;
+  }
+  int GetPathsCount()
+  {
+    return Paths.Count();
+  }
+  wxString & GetPathByIndex(int idx)
+  {
+    return Paths.Item(idx);
+  }
+  void SetCurrentPath(wxString & path)
+  {
+    CurrentPath = path;
+  }
+  wxString & GetCurrentPath()
+  {
+    return CurrentPath;
+  }
+  void SetError()
+  {
+    Error = true;
+  }
+  bool GetError()
+  {
+    return Error;
+  }
+  void Done()
+  {
+    Count++;
+  }
+  int GetCount()
+  {
+    return Count;
+  }
+  void RequestAbort()
+  {
+    AbortPending = true;
+  }
+  bool IsAbortPending()
+  {
+    return AbortPending;
+  }
+};
+
+class LoadRasterStyleDialog:public wxDialog
+{
+//
+// a dialog for adding new SLD/SE Raster Style
+//
+private:
+  MyFrame * MainFrame;
+  wxString Path;
+  wxArrayString Paths;
+  wxString CurrentPath;
+  bool Error;
+  int Count;
+  wxString ListDone;
+  RasterStylesLoadParams Params;
+public:
+    LoadRasterStyleDialog()
+  {;
+  }
+  bool Create(MyFrame * parent, wxArrayString & paths, wxString & path);
+  virtual ~ LoadRasterStyleDialog()
+  {;
+  }
+  void CreateControls();
+  void DoRunLoad(void);
+  bool RegisterRasterStyle(sqlite3_stmt * stmt, void *blob, int blob_size);
+  void OnCancel(wxCommandEvent & event);
+  void OnOk(wxCommandEvent & event);
+  void OnCmdAbort(wxCommandEvent & event);
+  void OnRequestStart(wxCommandEvent & event);
+  void OnRequestStop(wxCommandEvent & event);
+  void OnRequestSkip(wxCommandEvent & event);
+  void OnThreadFinished(wxCommandEvent & event);
+};
+
+class ReloadRasterStyleDialog:public wxDialog
+{
+//
+// a dialog for reloading an already existing SLD/SE Raster Style
+//
+private:
+  MyFrame * MainFrame;
+  wxString Path;
+  RasterCoverageStylesList *List;
+  wxGrid *GridCtrl;
+public:
+    ReloadRasterStyleDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent, wxString & path);
+  virtual ~ ReloadRasterStyleDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  bool DoReloadRasterStyle(int style_id, void *blob, int blob_size);
+  void OnCancel(wxCommandEvent & event);
+  void OnOk(wxCommandEvent & event);
+};
+
+class UnregisterRasterStyleDialog:public wxDialog
+{
+//
+// a dialog for unregistering an already existing SLD/SE Raster Style
+//
+private:
+  MyFrame * MainFrame;
+  RasterCoverageStylesList *List;
+  wxGrid *GridCtrl;
+public:
+    UnregisterRasterStyleDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ UnregisterRasterStyleDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  bool DoCheckUnreferencedRasterStyle(int style_id);
+  bool DoUnregisterRasterStyle(int style_id);
+  void OnCancel(wxCommandEvent & event);
+  void OnOk(wxCommandEvent & event);
+};
+
+class RasterCoverageSRID
+{
+// a Raster Coverage alternative SRID
+private:
+  int Srid;
+  wxString AuthName;
+  int AuthSrid;
+  wxString RefSysName;
+  bool Native;
+  bool Deleted;
+  RasterCoverageSRID *Next;
+public:
+    RasterCoverageSRID(bool native, int srid, wxString & auth_name,
+                       int auth_srid, wxString & name)
+  {
+    Srid = srid;
+    AuthName = auth_name;
+    AuthSrid = auth_srid;
+    RefSysName = name;
+    Native = native;
+    Deleted = false;
+    Next = NULL;
+  }
+   ~RasterCoverageSRID()
+  {;
+  }
+  int GetSrid()
+  {
+    return Srid;
+  }
+  wxString & GetAuthName()
+  {
+    return AuthName;
+  }
+  int GetAuthSrid()
+  {
+    return AuthSrid;
+  }
+  wxString & GetRefSysName()
+  {
+    return RefSysName;
+  }
+  bool IsNative()
+  {
+    return Native;
+  }
+  void MarkDeleted()
+  {
+    Deleted = true;
+  }
+  bool IsDeleted()
+  {
+    return Deleted;
+  }
+  RasterCoverageSRID *GetNext()
+  {
+    return Next;
+  }
+  void SetNext(RasterCoverageSRID * next)
+  {
+    Next = next;
+  }
+};
+
+class RasterCoverageSRIDsList
+{
+// a container for Raster Coverage alternative SRIDs
+private:
+  RasterCoverageSRID * First;
+  RasterCoverageSRID *Last;
+public:
+    RasterCoverageSRIDsList()
+  {
+    First = NULL;
+    Last = NULL;
+  }
+   ~RasterCoverageSRIDsList();
+  void Add(bool native, int srid, wxString & auth_name, int auth_srid,
+           wxString & name);
+  RasterCoverageSRID *GetFirst()
+  {
+    return First;
+  }
+  bool IsAlreadyDefinedSrid(int srid);
+  bool IsNativeSrid(int srid);
+  void MarkDeleted(int strid);
+};
+
+class RasterSRIDsDialog:public wxDialog
+{
+//
+// a dialog for handling Raster Coverage's alternative SRIDs
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  int CurrentRow;
+  int CurrentSRID;
+  RasterCoverageSRIDsList *List;
+  wxGrid *GridCtrl;
+public:
+    RasterSRIDsDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent, wxString & coverage);
+  virtual ~ RasterSRIDsDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  bool DoRegistetRasterCoverageSrid(int srid);
+  void OnRightClick(wxGridEvent & event);
+  void OnCmdRemoveSrid(wxCommandEvent & event);
+  void OnCmdAddSrid(wxCommandEvent & event);
+  void OnQuit(wxCommandEvent & event);
+};
+
+class RasterCoverageKeyword
+{
+// a Raster Coverage Keyword
+private:
+  wxString Keyword;
+  bool Deleted;
+  RasterCoverageKeyword *Next;
+public:
+    RasterCoverageKeyword(wxString & keyword)
+  {
+    Keyword = keyword;
+    Deleted = false;
+    Next = NULL;
+  }
+   ~RasterCoverageKeyword()
+  {;
+  }
+  wxString & GetKeyword()
+  {
+    return Keyword;
+  }
+  void MarkDeleted()
+  {
+    Deleted = true;
+  }
+  bool IsDeleted()
+  {
+    return Deleted;
+  }
+  RasterCoverageKeyword *GetNext()
+  {
+    return Next;
+  }
+  void SetNext(RasterCoverageKeyword * next)
+  {
+    Next = next;
+  }
+};
+
+class RasterCoverageKeywordsList
+{
+// a container for Raster Coverage Keywords
+private:
+  RasterCoverageKeyword * First;
+  RasterCoverageKeyword *Last;
+public:
+    RasterCoverageKeywordsList()
+  {
+    First = NULL;
+    Last = NULL;
+  }
+   ~RasterCoverageKeywordsList();
+  void Add(wxString & keyword);
+  RasterCoverageKeyword *GetFirst()
+  {
+    return First;
+  }
+  bool IsAlreadyDefinedKeyword(wxString & keyword);
+  void MarkDeleted(wxString & keyword);
+};
+
+class RasterKeywordsDialog:public wxDialog
+{
+//
+// a dialog for handling Raster Coverage's Keywords
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  int CurrentRow;
+  wxString Keyword;
+  RasterCoverageKeywordsList *List;
+  wxGrid *GridCtrl;
+public:
+    RasterKeywordsDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent, wxString & coverage);
+  virtual ~ RasterKeywordsDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  bool DoRegistetRasterCoverageKeyword(wxString & keyword);
+  void OnRightClick(wxGridEvent & event);
+  void OnCmdRemoveKeyword(wxCommandEvent & event);
+  void OnCmdAddKeyword(wxCommandEvent & event);
+  void OnQuit(wxCommandEvent & event);
+};
+
+class ExternalGraphicLoadParams
+{
+// a class wrapping External Graphic Import arguments
+private:
+  MyFrame * MainFrame;
+  class LoadExternalGraphicDialog *Dlg;
+  wxArrayString Paths;
+  wxString CurrentPath;
+  bool Error;
+  int Count;
+  bool AbortPending;
+public:
+    ExternalGraphicLoadParams()
+  {;
+  }
+   ~ExternalGraphicLoadParams()
+  {;
+  }
+  void Initialize(MyFrame * mother, LoadExternalGraphicDialog * dlg,
+                  wxArrayString & paths)
+  {
+    MainFrame = mother;
+    Dlg = dlg;
+    Paths = paths;
+    Error = false;
+    Count = 0;
+    AbortPending = false;
+  }
+  MyFrame *GetMainFrame()
+  {
+    return MainFrame;
+  }
+  LoadExternalGraphicDialog *GetDlg()
+  {
+    return Dlg;
+  }
+  int GetPathsCount()
+  {
+    return Paths.Count();
+  }
+  wxString & GetPathByIndex(int idx)
+  {
+    return Paths.Item(idx);
+  }
+  void SetCurrentPath(wxString & path)
+  {
+    CurrentPath = path;
+  }
+  wxString & GetCurrentPath()
+  {
+    return CurrentPath;
+  }
+  void SetError()
+  {
+    Error = true;
+  }
+  bool GetError()
+  {
+    return Error;
+  }
+  void Done()
+  {
+    Count++;
+  }
+  int GetCount()
+  {
+    return Count;
+  }
+  void RequestAbort()
+  {
+    AbortPending = true;
+  }
+  bool IsAbortPending()
+  {
+    return AbortPending;
+  }
+};
+
+class LoadExternalGraphicDialog:public wxDialog
+{
+//
+// a dialog for adding new External Graphic resource(s)
+//
+private:
+  MyFrame * MainFrame;
+  wxString Path;
+  wxArrayString Paths;
+  wxString CurrentPath;
+  bool Error;
+  int Count;
+  wxString ListDone;
+  ExternalGraphicLoadParams Params;
+public:
+    LoadExternalGraphicDialog()
+  {;
+  }
+  bool Create(MyFrame * parent, wxArrayString & paths, wxString & path);
+  virtual ~ LoadExternalGraphicDialog()
+  {;
+  }
+  void CreateControls();
+  void DoRunLoad(void);
+  bool RegisterExternalGraphic(sqlite3_stmt * stmt, const char *xlink_href,
+                               const char *title, const char *abstract,
+                               const char *filename, void *blob, int blob_size);
+  void OnCancel(wxCommandEvent & event);
+  void OnOk(wxCommandEvent & event);
+  void OnCmdAbort(wxCommandEvent & event);
+  void OnRequestStart(wxCommandEvent & event);
+  void OnRequestStop(wxCommandEvent & event);
+  void OnRequestSkip(wxCommandEvent & event);
+  void OnThreadFinished(wxCommandEvent & event);
+};
+
+class ExternalGraphic
+{
+// a class wrapping an External Graphic
+private:
+  wxString XLinkHref;
+  wxString Title;
+  wxString Abstract;
+  wxString MimeType;
+  wxImage Graphic;
+  ExternalGraphic *Next;
+  bool DoBuildGraphic(wxString & mime_type, const void *blob, int blob_sz);
+  void DoBuildDefaultGraphic();
+public:
+    ExternalGraphic(wxString & xlink_href, wxString & title,
+                    wxString & abstract, wxString & mime_type, const void *blob,
+                    int blob_sz);
+   ~ExternalGraphic()
+  {;
+  }
+  wxString & GetXLinkHref()
+  {
+    return XLinkHref;
+  }
+  wxString & GetTitle()
+  {
+    return Title;
+  }
+  wxString & GetAbstract()
+  {
+    return Abstract;
+  }
+  wxString & GetMimeType()
+  {
+    return MimeType;
+  }
+  wxImage *GetGraphic()
+  {
+    return &Graphic;
+  }
+  void SetNext(ExternalGraphic * next)
+  {
+    Next = next;
+  }
+  ExternalGraphic *GetNext()
+  {
+    return Next;
+  }
+};
+
+class ExternalGraphicList
+{
+// a class acting as a container of External Graphics
+private:
+  ExternalGraphic * First;
+  ExternalGraphic *Last;
+public:
+    ExternalGraphicList()
+  {
+    First = NULL;
+    Last = NULL;
+  }
+   ~ExternalGraphicList();
+  void Add(wxString & xlink_href, wxString & title, wxString & abstract,
+           wxString & mime_type, const void *blob, int blob_sz);
+  ExternalGraphic *GetFirst()
+  {
+    return First;
+  }
+  void FindByIndex(int idx, wxString & xlink_href, wxString & mime_type);
+  int FindByXLinkHref(wxString & xlink_href);
+};
+
+class UnregisterExternalGraphicDialog:public wxDialog
+{
+//
+// a dialog for unregistering an already existing External Graphic resource
+//
+private:
+  MyFrame * MainFrame;
+  ExternalGraphicList *List;
+  wxGrid *GridCtrl;
+public:
+    UnregisterExternalGraphicDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ UnregisterExternalGraphicDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  bool DoUnregisterExternalGraphic(const char *xlink_href);
+  void OnCancel(wxCommandEvent & event);
+  void OnOk(wxCommandEvent & event);
+};
+
+class TextFontLoadParams
+{
+// a class wrapping Text Font Import arguments
+private:
+  MyFrame * MainFrame;
+  class LoadTextFontDialog *Dlg;
+  wxArrayString Paths;
+  wxString CurrentPath;
+  bool Error;
+  int Count;
+  bool AbortPending;
+public:
+    TextFontLoadParams()
+  {;
+  }
+   ~TextFontLoadParams()
+  {;
+  }
+  void Initialize(MyFrame * mother, LoadTextFontDialog * dlg,
+                  wxArrayString & paths)
+  {
+    MainFrame = mother;
+    Dlg = dlg;
+    Paths = paths;
+    Error = false;
+    Count = 0;
+    AbortPending = false;
+  }
+  MyFrame *GetMainFrame()
+  {
+    return MainFrame;
+  }
+  LoadTextFontDialog *GetDlg()
+  {
+    return Dlg;
+  }
+  int GetPathsCount()
+  {
+    return Paths.Count();
+  }
+  wxString & GetPathByIndex(int idx)
+  {
+    return Paths.Item(idx);
+  }
+  void SetCurrentPath(wxString & path)
+  {
+    CurrentPath = path;
+  }
+  wxString & GetCurrentPath()
+  {
+    return CurrentPath;
+  }
+  void SetError()
+  {
+    Error = true;
+  }
+  bool GetError()
+  {
+    return Error;
+  }
+  void Done()
+  {
+    Count++;
+  }
+  int GetCount()
+  {
+    return Count;
+  }
+  void RequestAbort()
+  {
+    AbortPending = true;
+  }
+  bool IsAbortPending()
+  {
+    return AbortPending;
+  }
+};
+
+class LoadTextFontDialog:public wxDialog
+{
+//
+// a dialog for adding new Text Font resource(s)
+//
+private:
+  MyFrame * MainFrame;
+  wxString Path;
+  wxArrayString Paths;
+  wxString CurrentPath;
+  bool Error;
+  int Count;
+  wxString ListDone;
+  TextFontLoadParams Params;
+public:
+    LoadTextFontDialog()
+  {;
+  }
+  bool Create(MyFrame * parent, wxArrayString & paths, wxString & path);
+  virtual ~ LoadTextFontDialog()
+  {;
+  }
+  void CreateControls();
+  void DoRunLoad(void);
+  bool RegisterTextFont(sqlite3_stmt * stmt, const char *path);
+  void OnCancel(wxCommandEvent & event);
+  void OnOk(wxCommandEvent & event);
+  void OnCmdAbort(wxCommandEvent & event);
+  void OnRequestStart(wxCommandEvent & event);
+  void OnRequestStop(wxCommandEvent & event);
+  void OnRequestSkip(wxCommandEvent & event);
+  void OnThreadFinished(wxCommandEvent & event);
+};
+
+class TextFont
+{
+// a class wrapping a Text Font
+private:
+  wxString Facename;
+  bool Bold;
+  bool Italic;
+  wxImage *FontExample;
+  TextFont *Next;
+public:
+    TextFont(const void *priv_data, const unsigned char *blob, int blob_sz);
+   ~TextFont()
+  {
+    delete FontExample;
+  }
+  wxString & GetFacename()
+  {
+    return Facename;
+  }
+  bool IsBold()
+  {
+    return Bold;
+  }
+  bool IsItalic()
+  {
+    return Italic;
+  }
+  wxImage *GetFontExample()
+  {
+    return FontExample;
+  }
+  void SetNext(TextFont * next)
+  {
+    Next = next;
+  }
+  TextFont *GetNext()
+  {
+    return Next;
+  }
+};
+
+class TextFontList
+{
+// a class acting as a container of Text Font
+private:
+  TextFont * First;
+  TextFont *Last;
+public:
+    TextFontList()
+  {
+    First = NULL;
+    Last = NULL;
+  }
+   ~TextFontList();
+  void Add(const void *priv_data, const unsigned char *blob, int blob_sz);
+  TextFont *GetFirst()
+  {
+    return First;
+  }
+  void FindByIndex(int idx, wxString & face_name, int *style, int *weight);
+  int FindByFaceName(wxString & face_name);
+};
+
+class UnregisterTextFontDialog:public wxDialog
+{
+//
+// a dialog for unregistering an already existing Text Font
+//
+private:
+  MyFrame * MainFrame;
+  TextFontList *List;
+  wxGrid *GridCtrl;
+public:
+    UnregisterTextFontDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ UnregisterTextFontDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  bool DoUnregisterTextFont(int font_id);
+  void OnCancel(wxCommandEvent & event);
+  void OnOk(wxCommandEvent & event);
+};
+
+class VectorStylesLoadParams
+{
+// a class wrapping Vector Styles Import arguments
+private:
+  MyFrame * MainFrame;
+  class LoadVectorStyleDialog *Dlg;
+  wxArrayString Paths;
+  wxString CurrentPath;
+  bool Error;
+  int Count;
+  bool AbortPending;
+public:
+    VectorStylesLoadParams()
+  {;
+  }
+   ~VectorStylesLoadParams()
+  {;
+  }
+  void Initialize(MyFrame * mother, LoadVectorStyleDialog * dlg,
+                  wxArrayString & paths)
+  {
+    MainFrame = mother;
+    Dlg = dlg;
+    Paths = paths;
+    Error = false;
+    Count = 0;
+    AbortPending = false;
+  }
+  MyFrame *GetMainFrame()
+  {
+    return MainFrame;
+  }
+  LoadVectorStyleDialog *GetDlg()
+  {
+    return Dlg;
+  }
+  int GetPathsCount()
+  {
+    return Paths.Count();
+  }
+  wxString & GetPathByIndex(int idx)
+  {
+    return Paths.Item(idx);
+  }
+  void SetCurrentPath(wxString & path)
+  {
+    CurrentPath = path;
+  }
+  wxString & GetCurrentPath()
+  {
+    return CurrentPath;
+  }
+  void SetError()
+  {
+    Error = true;
+  }
+  bool GetError()
+  {
+    return Error;
+  }
+  void Done()
+  {
+    Count++;
+  }
+  int GetCount()
+  {
+    return Count;
+  }
+  void RequestAbort()
+  {
+    AbortPending = true;
+  }
+  bool IsAbortPending()
+  {
+    return AbortPending;
+  }
+};
+
+class VectorCoverageStyle
+{
+// an SLD/SE Vector style
+private:
+  int StyleID;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  wxString SchemaValidated;
+  wxString SchemaURI;
+  bool Selected;
+  VectorCoverageStyle *Next;
+public:
+    VectorCoverageStyle(int style_id, wxString & name, wxString & title,
+                        wxString & abstract, wxString & validated,
+                        wxString & schema_uri);
+   ~VectorCoverageStyle()
+  {;
+  }
+  int GetStyleID()
+  {
+    return StyleID;
+  }
+  wxString & GetName()
+  {
+    return Name;
+  }
+  wxString & GetTitle()
+  {
+    return Title;
+  }
+  wxString & GetAbstract()
+  {
+    return Abstract;
+  }
+  wxString & GetSchemaValidated()
+  {
+    return SchemaValidated;
+  }
+  wxString & GetSchemaURI()
+  {
+    return SchemaURI;
+  }
+  void MarkSelected()
+  {
+    Selected = true;
+  }
+  bool IsSelected()
+  {
+    return Selected;
+  }
+  VectorCoverageStyle *GetNext()
+  {
+    return Next;
+  }
+  void SetNext(VectorCoverageStyle * next)
+  {
+    Next = next;
+  }
+};
+
+class VectorCoverageStylesList
+{
+// a container for Vector Coverage SLD/SE styles
+private:
+  VectorCoverageStyle * First;
+  VectorCoverageStyle *Last;
+public:
+    VectorCoverageStylesList();
+   ~VectorCoverageStylesList();
+  void Add(int style_id, wxString & name, wxString & title, wxString & abstract,
+           wxString & validated, wxString & schema_uri);
+  void MarkSelected(int stileId);
+  VectorCoverageStyle *GetFirst()
+  {
+    return First;
+  }
+};
+
+class LoadVectorStyleDialog:public wxDialog
+{
+//
+// a dialog for adding new SLD/SE Vector Style
+//
+private:
+  MyFrame * MainFrame;
+  wxString Path;
+  wxArrayString Paths;
+  wxString CurrentPath;
+  bool Error;
+  int Count;
+  wxString ListDone;
+  VectorStylesLoadParams Params;
+public:
+    LoadVectorStyleDialog()
+  {;
+  }
+  bool Create(MyFrame * parent, wxArrayString & paths, wxString & path);
+  virtual ~ LoadVectorStyleDialog()
+  {;
+  }
+  void CreateControls();
+  void DoRunLoad(void);
+  bool RegisterVectorStyle(sqlite3_stmt * stmt, void *blob, int blob_size);
+  void OnCancel(wxCommandEvent & event);
+  void OnOk(wxCommandEvent & event);
+  void OnCmdAbort(wxCommandEvent & event);
+  void OnRequestStart(wxCommandEvent & event);
+  void OnRequestStop(wxCommandEvent & event);
+  void OnRequestSkip(wxCommandEvent & event);
+  void OnThreadFinished(wxCommandEvent & event);
+};
+
+class ReloadVectorStyleDialog:public wxDialog
+{
+//
+// a dialog for reloading an already existing SLD/SE Vector Style
+//
+private:
+  MyFrame * MainFrame;
+  wxString Path;
+  VectorCoverageStylesList *List;
+  wxGrid *GridCtrl;
+public:
+    ReloadVectorStyleDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent, wxString & path);
+  virtual ~ ReloadVectorStyleDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  bool DoReloadVectorStyle(int style_id, void *blob, int blob_size);
+  void OnCancel(wxCommandEvent & event);
+  void OnOk(wxCommandEvent & event);
+};
+
+class UnregisterVectorStyleDialog:public wxDialog
+{
+//
+// a dialog for unregistering an already existing SLD/SE Vector Style
+//
+private:
+  MyFrame * MainFrame;
+  VectorCoverageStylesList *List;
+  wxGrid *GridCtrl;
+public:
+    UnregisterVectorStyleDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ UnregisterVectorStyleDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  bool DoCheckUnreferencedVectorStyle(int style_id);
+  bool DoUnregisterVectorStyle(int style_id);
+  void OnCancel(wxCommandEvent & event);
+  void OnOk(wxCommandEvent & event);
+};
+
+class VectorUnregisterDialog:public wxDialog
+{
+//
+// a dialog supporting Unregister Vector
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  wxString Title;
+  wxString Abstract;
+  wxString Type;
+public:
+    VectorUnregisterDialog()
+  {;
+  }
+  bool Create(MyFrame * parent, wxString & coverage, wxString & title,
+              wxString & abstract, wxString & type);
+  virtual ~ VectorUnregisterDialog()
+  {;
+  }
+  void CreateControls();
+  bool DoVectorUnregister(void);
+  void OnOk(wxCommandEvent & event);
+};
+
+class VectorCoverageStylesDialog:public wxDialog
+{
+//
+// a dialog for handling SLD/SE Vector Coverage's Styles
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  int CurrentRow;
+  int CurrentStyleID;
+  VectorCoverageStylesList *List;
+  wxGrid *GridCtrl;
+public:
+    VectorCoverageStylesDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent, wxString & coverage);
+  virtual ~ VectorCoverageStylesDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  void DoRegistetVectorCoverageStyles(class ListVectorStylesDialog * dlg);
+  void OnRightClick(wxGridEvent & event);
+  void OnCmdRemoveStyle(wxCommandEvent & event);
+  void OnAddStyle(wxCommandEvent & event);
+  void OnQuit(wxCommandEvent & event);
+};
+
+class ListVectorStylesDialog:public wxDialog
+{
+//
+// a dialog for listing and selecting SLD/SE Vector Styles
+//
+private:
+  MyFrame * MainFrame;
+  VectorCoverageStylesList *List;
+  wxGrid *GridCtrl;
+public:
+    ListVectorStylesDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ ListVectorStylesDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  int GetSelectedCount();
+  int GetSelectedStyleId(int idx);
+  void OnOk(wxCommandEvent & event);
+};
+
+class CandidateVectorCoverage
+{
+// an SLD/SE Vector style
+private:
+  wxString TableName;
+  wxString GeometryColumn;
+  int Srid;
+  wxString GeometryType;
+  bool VectorCoverage;
+  bool RasterCoverage;
+  CandidateVectorCoverage *Next;
+public:
+    CandidateVectorCoverage(wxString & table, wxString & geometry, int srid,
+                            wxString & type)
+  {
+    TableName = table;
+    GeometryColumn = geometry;
+    Srid = srid;
+    GeometryType = type;
+    VectorCoverage = false;
+    RasterCoverage = false;
+    Next = NULL;
+  }
+   ~CandidateVectorCoverage()
+  {;
+  }
+  wxString & GetTableName()
+  {
+    return TableName;
+  }
+  wxString & GetGeometryColumn()
+  {
+    return GeometryColumn;
+  }
+  int GetSrid()
+  {
+    return Srid;
+  }
+  wxString & GetGeometryType()
+  {
+    return GeometryType;
+  }
+  void MarkVectorCoverage()
+  {
+    VectorCoverage = true;
+  }
+  bool IsVectorCoverage()
+  {
+    return VectorCoverage;
+  }
+  void MarkRasterCoverage()
+  {
+    RasterCoverage = true;
+  }
+  bool IsRasterCoverage()
+  {
+    return RasterCoverage;
+  }
+  CandidateVectorCoverage *GetNext()
+  {
+    return Next;
+  }
+  void SetNext(CandidateVectorCoverage * next)
+  {
+    Next = next;
+  }
+};
+
+class CandidateVectorCoveragesList
+{
+// a container for candidate Vector Coverages
+private:
+  CandidateVectorCoverage * First;
+  CandidateVectorCoverage *Last;
+public:
+    CandidateVectorCoveragesList()
+  {
+    First = NULL;
+    Last = NULL;
+  }
+   ~CandidateVectorCoveragesList();
+  void Add(wxString & table_name, wxString & geometry, int srid,
+           wxString & type);
+  void MarkVectorCoverage(wxString & table, wxString & geometry);
+  void MarkRasterCoverage(wxString & table, wxString & geometry);
+  CandidateVectorCoverage *GetFirst()
+  {
+    return First;
+  }
+};
+
+class VectorRegisterDialog:public wxDialog
+{
+//
+// a dialog for Register Vector Coverage
+//
+private:
+  MyFrame * MainFrame;
+  CandidateVectorCoveragesList *List;
+  wxGrid *GridCtrl;
+  wxString CoverageName;
+  wxString TableName;
+  wxString GeometryColumn;
+  wxString Title;
+  wxString Abstract;
+public:
+    VectorRegisterDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ VectorRegisterDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  wxString & GetCoverageName()
+  {
+    return CoverageName;
+  }
+  wxString & GetTableName()
+  {
+    return TableName;
+  }
+  wxString & GetGeometryColumn()
+  {
+    return GeometryColumn;
+  }
+  wxString & GetTitle()
+  {
+    return Title;
+  }
+  wxString & GetAbstract()
+  {
+    return Abstract;
+  }
+  void OnOk(wxCommandEvent & event);
+};
+
+class VectorCoverageSRID
+{
+// a Vector Coverage alternative SRID
+private:
+  int Srid;
+  wxString AuthName;
+  int AuthSrid;
+  wxString RefSysName;
+  bool Native;
+  bool Deleted;
+  VectorCoverageSRID *Next;
+public:
+    VectorCoverageSRID(bool native, int srid, wxString & auth_name,
+                       int auth_srid, wxString & name)
+  {
+    Srid = srid;
+    AuthName = auth_name;
+    AuthSrid = auth_srid;
+    RefSysName = name;
+    Native = native;
+    Deleted = false;
+    Next = NULL;
+  }
+   ~VectorCoverageSRID()
+  {;
+  }
+  int GetSrid()
+  {
+    return Srid;
+  }
+  wxString & GetAuthName()
+  {
+    return AuthName;
+  }
+  int GetAuthSrid()
+  {
+    return AuthSrid;
+  }
+  wxString & GetRefSysName()
+  {
+    return RefSysName;
+  }
+  bool IsNative()
+  {
+    return Native;
+  }
+  void MarkDeleted()
+  {
+    Deleted = true;
+  }
+  bool IsDeleted()
+  {
+    return Deleted;
+  }
+  VectorCoverageSRID *GetNext()
+  {
+    return Next;
+  }
+  void SetNext(VectorCoverageSRID * next)
+  {
+    Next = next;
+  }
+};
+
+class VectorCoverageSRIDsList
+{
+// a container for Vector Coverage alternative SRIDs
+private:
+  VectorCoverageSRID * First;
+  VectorCoverageSRID *Last;
+public:
+    VectorCoverageSRIDsList()
+  {
+    First = NULL;
+    Last = NULL;
+  }
+   ~VectorCoverageSRIDsList();
+  void Add(bool native, int srid, wxString & auth_name, int auth_srid,
+           wxString & name);
+  VectorCoverageSRID *GetFirst()
+  {
+    return First;
+  }
+  bool IsAlreadyDefinedSrid(int srid);
+  bool IsNativeSrid(int srid);
+  void MarkDeleted(int strid);
+};
+
+class VectorSRIDsDialog:public wxDialog
+{
+//
+// a dialog for handling Vector Coverage's alternative SRIDs
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  int CurrentRow;
+  int CurrentSRID;
+  VectorCoverageSRIDsList *List;
+  wxGrid *GridCtrl;
+public:
+    VectorSRIDsDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent, wxString & coverage);
+  virtual ~ VectorSRIDsDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  bool DoRegistetVectorCoverageSrid(int srid);
+  void OnRightClick(wxGridEvent & event);
+  void OnCmdRemoveSrid(wxCommandEvent & event);
+  void OnCmdAddSrid(wxCommandEvent & event);
+  void OnQuit(wxCommandEvent & event);
+};
+
+class VectorCoverageKeyword
+{
+// a Vector Coverage Keyword
+private:
+  wxString Keyword;
+  bool Deleted;
+  VectorCoverageKeyword *Next;
+public:
+    VectorCoverageKeyword(wxString & keyword)
+  {
+    Keyword = keyword;
+    Deleted = false;
+    Next = NULL;
+  }
+   ~VectorCoverageKeyword()
+  {;
+  }
+  wxString & GetKeyword()
+  {
+    return Keyword;
+  }
+  void MarkDeleted()
+  {
+    Deleted = true;
+  }
+  bool IsDeleted()
+  {
+    return Deleted;
+  }
+  VectorCoverageKeyword *GetNext()
+  {
+    return Next;
+  }
+  void SetNext(VectorCoverageKeyword * next)
+  {
+    Next = next;
+  }
+};
+
+class VectorCoverageKeywordsList
+{
+// a container for Vector Coverage Keywords
+private:
+  VectorCoverageKeyword * First;
+  VectorCoverageKeyword *Last;
+public:
+    VectorCoverageKeywordsList()
+  {
+    First = NULL;
+    Last = NULL;
+  }
+   ~VectorCoverageKeywordsList();
+  void Add(wxString & keyword);
+  VectorCoverageKeyword *GetFirst()
+  {
+    return First;
+  }
+  bool IsAlreadyDefinedKeyword(wxString & keyword);
+  void MarkDeleted(wxString & keyword);
+};
+
+class VectorKeywordsDialog:public wxDialog
+{
+//
+// a dialog for handling Vector Coverage's Keywords
+//
+private:
+  MyFrame * MainFrame;
+  wxString CoverageName;
+  int CurrentRow;
+  wxString Keyword;
+  VectorCoverageKeywordsList *List;
+  wxGrid *GridCtrl;
+public:
+    VectorKeywordsDialog()
+  {
+    List = NULL;
+  }
+  bool Create(MyFrame * parent, wxString & coverage);
+  virtual ~ VectorKeywordsDialog()
+  {
+    if (List != NULL)
+      delete List;
+  }
+  void CreateControls();
+  bool DoRegistetVectorCoverageKeyword(wxString & keyword);
+  void OnRightClick(wxGridEvent & event);
+  void OnCmdRemoveKeyword(wxCommandEvent & event);
+  void OnCmdAddKeyword(wxCommandEvent & event);
+  void OnQuit(wxCommandEvent & event);
+};
+
+class RasterSymbolizerContrastDialog:public wxDialog
+{
+//
+// a dialog for creating an SLD/SE RasterSymbolizer 
+// of the ContrastEnhancement type
+//
+private:
+  MyFrame * MainFrame;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  double Opacity;
+  bool Normalize;
+  bool Histogram;
+  bool Gamma;
+  double GammaValue;
+  bool MinScale;
+  bool MaxScale;
+  double MinScaleDenominator;
+  double MaxScaleDenominator;
+  bool RetrieveParams();
+  char *DoCreateSymbolizerXML();
+  char *DoCreateCoverageXML();
+public:
+    RasterSymbolizerContrastDialog()
+  {;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ RasterSymbolizerContrastDialog()
+  {;
+  }
+  void CreateControls();
+  void OnQuit(wxCommandEvent & event);
+  void OnInsert(wxCommandEvent & event);
+  void OnExport(wxCommandEvent & event);
+  void OnCopy(wxCommandEvent & event);
+  void OnCmdModeChanged(wxCommandEvent & event);
+  void OnCmdScaleChanged(wxCommandEvent & event);
+};
+
+class RasterSymbolizerChannelRgbDialog:public wxDialog
+{
+//
+// a dialog for creating an SLD/SE RasterSymbolizer 
+// of the ChannelSelection (RGB) type
+//
+private:
+  MyFrame * MainFrame;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  double Opacity;
+  int RedBand;
+  int GreenBand;
+  int BlueBand;
+  bool Normalize;
+  bool Histogram;
+  bool Gamma;
+  double GammaValue;
+  bool MinScale;
+  bool MaxScale;
+  double MinScaleDenominator;
+  double MaxScaleDenominator;
+  bool RetrieveParams();
+  char *DoCreateSymbolizerXML();
+  char *DoCreateCoverageXML();
+public:
+    RasterSymbolizerChannelRgbDialog()
+  {;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ RasterSymbolizerChannelRgbDialog()
+  {;
+  }
+  void CreateControls();
+  void OnQuit(wxCommandEvent & event);
+  void OnInsert(wxCommandEvent & event);
+  void OnExport(wxCommandEvent & event);
+  void OnCopy(wxCommandEvent & event);
+  void OnCmdModeChanged(wxCommandEvent & event);
+  void OnCmdScaleChanged(wxCommandEvent & event);
+};
+
+class RasterSymbolizerChannelGrayDialog:public wxDialog
+{
+//
+// a dialog for creating an SLD/SE RasterSymbolizer 
+// of the ChannelSelection (Gray) type
+//
+private:
+  MyFrame * MainFrame;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  double Opacity;
+  int GrayBand;
+  bool Normalize;
+  bool Histogram;
+  bool Gamma;
+  double GammaValue;
+  bool MinScale;
+  bool MaxScale;
+  double MinScaleDenominator;
+  double MaxScaleDenominator;
+  bool RetrieveParams();
+  char *DoCreateSymbolizerXML();
+  char *DoCreateCoverageXML();
+public:
+    RasterSymbolizerChannelGrayDialog()
+  {;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ RasterSymbolizerChannelGrayDialog()
+  {;
+  }
+  void CreateControls();
+  void OnQuit(wxCommandEvent & event);
+  void OnInsert(wxCommandEvent & event);
+  void OnExport(wxCommandEvent & event);
+  void OnCopy(wxCommandEvent & event);
+  void OnCmdModeChanged(wxCommandEvent & event);
+  void OnCmdScaleChanged(wxCommandEvent & event);
+};
+
+class ColorMapEntry
+{
+//
+// a class wrapping a ColorMap entry
+//
+private:
+  double Value;
+  wxString Color;
+  ColorMapEntry *Prev;
+  ColorMapEntry *Next;
+public:
+    ColorMapEntry(double value, wxString & color)
+  {
+    Value = value;
+    Color = color.MakeLower();
+    Prev = NULL;
+    Next = NULL;
+  }
+   ~ColorMapEntry()
+  {;
+  }
+  double GetValue()
+  {
+    return Value;
+  }
+  void SetColor(wxString & color)
+  {
+    Color = color;
+  }
+  wxString & GetColor()
+  {
+    return Color;
+  }
+  void SetPrev(ColorMapEntry * ptr)
+  {
+    Prev = ptr;
+  }
+  ColorMapEntry *GetPrev()
+  {
+    return Prev;
+  }
+  void SetNext(ColorMapEntry * ptr)
+  {
+    Next = ptr;
+  }
+  ColorMapEntry *GetNext()
+  {
+    return Next;
+  }
+  static bool IsValidColor(wxString & color);
+  static void GetWxColor(wxString & color, wxColour & clr);
+  static unsigned char ParseHex(unsigned char hi, unsigned char lo);
+};
+
+class ColorMapCategorize
+{
+//
+// a class wrapping a ColorMap of the Categorize Type
+//
+private:
+  wxString FirstColor;
+  ColorMapEntry *First;
+  ColorMapEntry *Last;
+public:
+    ColorMapCategorize()
+  {
+    FirstColor = wxT("#000000");
+    First = NULL;
+    Last = NULL;
+  }
+   ~ColorMapCategorize();
+  void SetFirstColor(wxString & color)
+  {
+    FirstColor = color;
+  }
+  wxString & GetFirstColor()
+  {
+    return FirstColor;
+  }
+  void Add(double value, wxString & color);
+  void Remove(double value);
+  ColorMapEntry *GetFirst()
+  {
+    return First;
+  }
+};
+
+class ColorMapInterpolate
+{
+//
+// a class wrapping a ColorMap of the Interpolate Type
+//
+private:
+  ColorMapEntry * First;
+  ColorMapEntry *Last;
+public:
+    ColorMapInterpolate()
+  {
+    First = NULL;
+    Last = NULL;
+  }
+   ~ColorMapInterpolate();
+  void Add(double value, wxString & color);
+  void Remove(double value);
+  ColorMapEntry *GetFirst()
+  {
+    return First;
+  }
+};
+
+class RasterSymbolizerCategorizeDialog:public wxDialog
+{
+//
+// a dialog for creating an SLD/SE RasterSymbolizer 
+// of the ColorMap Categorize type
+//
+private:
+  MyFrame * MainFrame;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  double Opacity;
+  ColorMapCategorize Map;
+  bool ShadedRelief;
+  double ReliefFactor;
+  wxGrid *GridCtrl;
+  int CurrentRow;
+  double CurrentValue;
+  bool MinScale;
+  bool MaxScale;
+  double MinScaleDenominator;
+  double MaxScaleDenominator;
+  bool RetrieveParams();
+  char *DoCreateSymbolizerXML();
+  char *DoCreateCoverageXML();
+  void RefreshGrid();
+public:
+    RasterSymbolizerCategorizeDialog()
+  {;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ RasterSymbolizerCategorizeDialog()
+  {;
+  }
+  void CreateControls();
+  void OnCmdAddEntry(wxCommandEvent & event);
+  void OnCmdRemoveEntry(wxCommandEvent & event);
+  void OnQuit(wxCommandEvent & event);
+  void OnInsert(wxCommandEvent & event);
+  void OnExport(wxCommandEvent & event);
+  void OnCopy(wxCommandEvent & event);
+  void OnShadedChanged(wxCommandEvent & event);
+  void OnCmdColorPicker(wxCommandEvent & event);
+  void OnCmdAdd(wxCommandEvent & event);
+  void OnCmdRemove(wxCommandEvent & event);
+  void OnRightClick(wxGridEvent & event);
+  void OnCellSelected(wxGridEvent & event);
+  void OnCmdScaleChanged(wxCommandEvent & event);
+};
+
+class RasterSymbolizerInterpolateDialog:public wxDialog
+{
+//
+// a dialog for creating an SLD/SE RasterSymbolizer 
+// of the ColorMap Interpolate type
+//
+private:
+  MyFrame * MainFrame;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  double Opacity;
+  wxString Fallback;
+  ColorMapInterpolate Map;
+  bool ShadedRelief;
+  double ReliefFactor;
+  wxGrid *GridCtrl;
+  int CurrentRow;
+  double CurrentValue;
+  bool MinScale;
+  bool MaxScale;
+  double MinScaleDenominator;
+  double MaxScaleDenominator;
+  bool RetrieveParams();
+  char *DoCreateSymbolizerXML();
+  char *DoCreateCoverageXML();
+  void RefreshGrid();
+public:
+    RasterSymbolizerInterpolateDialog()
+  {;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ RasterSymbolizerInterpolateDialog()
+  {;
+  }
+  void CreateControls();
+  void OnCmdAddEntry(wxCommandEvent & event);
+  void OnCmdRemoveEntry(wxCommandEvent & event);
+  void OnQuit(wxCommandEvent & event);
+  void OnInsert(wxCommandEvent & event);
+  void OnExport(wxCommandEvent & event);
+  void OnCopy(wxCommandEvent & event);
+  void OnShadedChanged(wxCommandEvent & event);
+  void OnCmdColorPicker(wxCommandEvent & event);
+  void OnCmdAdd(wxCommandEvent & event);
+  void OnCmdRemove(wxCommandEvent & event);
+  void OnRightClick(wxGridEvent & event);
+  void OnCellSelected(wxGridEvent & event);
+  void OnCmdScaleChanged(wxCommandEvent & event);
+};
+
+class RasterSymbolizerShadedReliefDialog:public wxDialog
+{
+//
+// a dialog for creating an SLD/SE RasterSymbolizer 
+// of the ChannelSelection (Gray) type
+//
+private:
+  MyFrame * MainFrame;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  double Opacity;
+  double ReliefFactor;
+  bool MinScale;
+  bool MaxScale;
+  double MinScaleDenominator;
+  double MaxScaleDenominator;
+  bool RetrieveParams();
+  char *DoCreateSymbolizerXML();
+  char *DoCreateCoverageXML();
+public:
+    RasterSymbolizerShadedReliefDialog()
+  {;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ RasterSymbolizerShadedReliefDialog()
+  {;
+  }
+  void CreateControls();
+  void OnQuit(wxCommandEvent & event);
+  void OnInsert(wxCommandEvent & event);
+  void OnExport(wxCommandEvent & event);
+  void OnCopy(wxCommandEvent & event);
+  void OnCmdScaleChanged(wxCommandEvent & event);
+};
+
+class RasterSymbolizerMonochromeDialog:public wxDialog
+{
+//
+// a dialog for creating an SLD/SE RasterSymbolizer 
+// of the Recolored Monochrome type
+//
+private:
+  MyFrame * MainFrame;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  double Opacity;
+  wxString Color;
+  bool MinScale;
+  bool MaxScale;
+  double MinScaleDenominator;
+  double MaxScaleDenominator;
+  bool RetrieveParams();
+  char *DoCreateSymbolizerXML();
+  char *DoCreateCoverageXML();
+public:
+    RasterSymbolizerMonochromeDialog()
+  {;
+  }
+  bool Create(MyFrame * parent);
+  virtual ~ RasterSymbolizerMonochromeDialog()
+  {;
+  }
+  void CreateControls();
+  void OnQuit(wxCommandEvent & event);
+  void OnInsert(wxCommandEvent & event);
+  void OnExport(wxCommandEvent & event);
+  void OnCopy(wxCommandEvent & event);
+  void OnCmdScaleChanged(wxCommandEvent & event);
+  void OnCmdColorPicker(wxCommandEvent & event);
+  void OnCmdColorChanged(wxCommandEvent & event);
+};
+
+class MyGraphicCellRenderer:public wxGridCellRenderer
+{
+// a Grid CellRenderer supporting a Graphic Image
+private:
+  wxImage * Graphic;
+public:
+  virtual wxGridCellRenderer * Clone() const
+  {
+    return new MyGraphicCellRenderer;
+  }
+  virtual void Draw(wxGrid & grid, wxGridCellAttr & attr, wxDC & dc,
+                    const wxRect & rect, int row, int col, bool isSelected);
+  virtual wxSize GetBestSize(wxGrid & grid, wxGridCellAttr & attr, wxDC & dc,
+                             int row, int col)
+  {
+    return wxSize(48, 24);
+  }
+  void SetGraphic(wxImage * graphic)
+  {
+    Graphic = graphic;
+  }
+};
+
+class MyFontCellRenderer:public wxGridCellRenderer
+{
+// a Grid CellRenderer supporting a Text Font
+private:
+  wxImage * FontExample;
+public:
+  virtual wxGridCellRenderer * Clone() const
+  {
+    return new MyFontCellRenderer;
+  }
+  virtual void Draw(wxGrid & grid, wxGridCellAttr & attr, wxDC & dc,
+                    const wxRect & rect, int row, int col, bool isSelected);
+  virtual wxSize GetBestSize(wxGrid & grid, wxGridCellAttr & attr, wxDC & dc,
+                             int row, int col)
+  {
+    return wxSize(600, 22);
+  }
+  void SetFontExample(wxImage * example)
+  {
+    FontExample = example;
+  }
+};
+
+class SymbolizerPreview:public wxStaticBitmap
+{
+//
+// a window to show a Vector Symbolizer Preview
+//
+private:
+  wxPropertySheetDialog * Parent;
+public:
+  SymbolizerPreview(wxPropertySheetDialog * parent, wxWindow * panel,
+                    wxWindowID id, const wxBitmap & bmp, wxSize const &size);
+    virtual ~ SymbolizerPreview()
+  {;
+  }
+};
+
+class SimpleLineSymbolizerDialog:public wxPropertySheetDialog
+{
+//
+// a dialog for creating an SLD/SE LineSymbolizer 
+// of the simple type
+//
+private:
+  MyFrame * MainFrame;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  unsigned char Uom;
+  bool MinScale;
+  bool MaxScale;
+  double MinScaleDenominator;
+  double MaxScaleDenominator;
+  double PerpendicularOffset1;
+  double Stroke1Opacity;
+  bool HasGraphic1;
+  wxString Stroke1Color;
+  wxString Stroke1XLinkHref;
+  wxString Stroke1MimeType;
+  bool EnableStroke1Replacement;
+  wxString Stroke1ColorReplacement;
+  ExternalGraphicList *List;
+  wxGrid *GridCtrl1;
+  double Stroke1Width;
+  int Stroke1LineJoin;
+  int Stroke1LineCap;
+  int Stroke1DashCount;
+  double *Stroke1DashArray;
+  double Stroke1DashOffset;
+  bool EnableStroke2;
+  double PerpendicularOffset2;
+  double Stroke2Opacity;
+  bool HasGraphic2;
+  wxString Stroke2Color;
+  wxString Stroke2XLinkHref;
+  bool EnableStroke2Replacement;
+  wxString Stroke2ColorReplacement;
+  wxString Stroke2MimeType;
+  wxGrid *GridCtrl2;
+  double Stroke2Width;
+  int Stroke2LineJoin;
+  int Stroke2LineCap;
+  int Stroke2DashCount;
+  double *Stroke2DashArray;
+  double Stroke2DashOffset;
+  bool EnableStroke3;
+  double PerpendicularOffset3;
+  double Stroke3Opacity;
+  bool HasGraphic3;
+  wxString Stroke3Color;
+  wxString Stroke3XLinkHref;
+  bool EnableStroke3Replacement;
+  wxString Stroke3ColorReplacement;
+  wxString Stroke3MimeType;
+  wxGrid *GridCtrl3;
+  double Stroke3Width;
+  int Stroke3LineJoin;
+  int Stroke3LineCap;
+  int Stroke3DashCount;
+  double *Stroke3DashArray;
+  double Stroke3DashOffset;
+  unsigned char PreviewBackground;
+  wxPanel *CreateMainPage(wxWindow * book);
+  wxPanel *CreateStroke1Page(wxWindow * book);
+  wxPanel *CreateStroke2Page(wxWindow * book);
+  wxPanel *CreateStroke3Page(wxWindow * book);
+  wxPanel *CreatePreviewPage(wxWindow * book);
+  void CreateButtons();
+  bool FinalValidityCheck();
+  bool RetrieveMainPage();
+  bool RetrieveStroke1Page(bool check = true);
+  bool RetrieveStroke2Page(bool check = true);
+  bool RetrieveStroke3Page(bool check = true);
+  bool RetrievePreviewPage();
+  void UpdateMainPage();
+  void UpdateStroke1Page();
+  void UpdateStroke2Page();
+  void UpdateStroke3Page();
+  void UpdatePreviewPage();
+  char *DoCreateSymbolizerXML();
+  char *DoCreateFeatureTypeXML();
+  void DrawPreview(int horz, int vert);
+  bool DoParseDashArray(wxString & str, int which);
+  void NormalizedDashArray(wxString & str, int which, char delimiter = ',');
+  void PrepareLinestringPath(void *ctx, double perpendicular_offset);
+  wxBitmap PreviewBackBitmap;
+public:
+    SimpleLineSymbolizerDialog();
+  bool Create(MyFrame * parent);
+    virtual ~ SimpleLineSymbolizerDialog();
+  void OnQuit(wxCommandEvent & event);
+  void OnInsert(wxCommandEvent & event);
+  void OnExport(wxCommandEvent & event);
+  void OnCopy(wxCommandEvent & event);
+  void OnPageChanging(wxNotebookEvent & event);
+  void OnPageChanged(wxNotebookEvent & event);
+  void OnCmdUomChanged(wxCommandEvent & event);
+  void OnCmdScaleChanged(wxCommandEvent & event);
+  void OnCmdStroke1TypeChanged(wxCommandEvent & event);
+  void OnCmdStroke2TypeChanged(wxCommandEvent & event);
+  void OnCmdStroke3TypeChanged(wxCommandEvent & event);
+  void OnCmdColor1Changed(wxCommandEvent & event);
+  void OnCmdColor2Changed(wxCommandEvent & event);
+  void OnCmdColor3Changed(wxCommandEvent & event);
+  void OnCmdColor1Picker(wxCommandEvent & event);
+  void OnCmdColor2Picker(wxCommandEvent & event);
+  void OnCmdColor3Picker(wxCommandEvent & event);
+  void OnCmdReplacement1Changed(wxCommandEvent & event);
+  void OnCmdReplacement2Changed(wxCommandEvent & event);
+  void OnCmdReplacement3Changed(wxCommandEvent & event);
+  void OnCmdLineJoin1Changed(wxCommandEvent & event);
+  void OnCmdLineJoin2Changed(wxCommandEvent & event);
+  void OnCmdLineJoin3Changed(wxCommandEvent & event);
+  void OnCmdLineCap1Changed(wxCommandEvent & event);
+  void OnCmdLineCap2Changed(wxCommandEvent & event);
+  void OnCmdLineCap3Changed(wxCommandEvent & event);
+  void OnCmdStroke2Changed(wxCommandEvent & event);
+  void OnCmdStroke3Changed(wxCommandEvent & event);
+  void OnCmdStroke1EnableReplacementChanged(wxCommandEvent & event);
+  void OnCmdStroke2EnableReplacementChanged(wxCommandEvent & event);
+  void OnCmdStroke3EnableReplacementChanged(wxCommandEvent & event);
+  void OnCmdBackgroundChanged(wxCommandEvent & event);
+};
+
+class SimplePolygonSymbolizerDialog:public wxPropertySheetDialog
+{
+//
+// a dialog for creating an SLD/SE PolygonSymbolizer 
+// of the simple type
+//
+private:
+  MyFrame * MainFrame;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  unsigned char Uom;
+  bool MinScale;
+  bool MaxScale;
+  double MinScaleDenominator;
+  double MaxScaleDenominator;
+  double DisplacementX1;
+  double DisplacementY1;
+  double PerpendicularOffset1;
+  bool EnableFill1;
+  double Fill1Opacity;
+  bool HasGraphicFill1;
+  wxString Fill1Color;
+  wxString Fill1XLinkHref;
+  wxString Fill1MimeType;
+  bool EnableFill1Replacement;
+  wxString Fill1ColorReplacement;
+  wxGrid *GridCtrl1;
+  bool EnableStroke1;
+  double Stroke1Opacity;
+  bool HasGraphicStroke1;
+  wxString Stroke1Color;
+  wxString Stroke1XLinkHref;
+  wxString Stroke1MimeType;
+  bool EnableStroke1Replacement;
+  wxString Stroke1ColorReplacement;
+  ExternalGraphicList *List;
+  wxGrid *GridCtrl2;
+  double Stroke1Width;
+  int Stroke1LineJoin;
+  int Stroke1LineCap;
+  int Stroke1DashCount;
+  double *Stroke1DashArray;
+  double Stroke1DashOffset;
+  bool EnablePolygon2;
+  double DisplacementX2;
+  double DisplacementY2;
+  double PerpendicularOffset2;
+  bool EnableFill2;
+  wxString Fill2MimeType;
+  bool EnableFill2Replacement;
+  wxString Fill2ColorReplacement;
+  double Fill2Opacity;
+  bool HasGraphicFill2;
+  wxString Fill2Color;
+  wxString Fill2XLinkHref;
+  wxGrid *GridCtrl3;
+  bool EnableStroke2;
+  double Stroke2Opacity;
+  bool HasGraphicStroke2;
+  wxString Stroke2Color;
+  wxString Stroke2XLinkHref;
+  wxString Stroke2MimeType;
+  bool EnableStroke2Replacement;
+  wxString Stroke2ColorReplacement;
+  wxGrid *GridCtrl4;
+  double Stroke2Width;
+  int Stroke2LineJoin;
+  int Stroke2LineCap;
+  int Stroke2DashCount;
+  double *Stroke2DashArray;
+  double Stroke2DashOffset;
+  unsigned char PreviewBackground;
+  wxPanel *CreateMainPage(wxWindow * book);
+  wxPanel *CreateStroke1Page(wxWindow * book);
+  wxPanel *CreateFill1Page(wxWindow * book);
+  wxPanel *CreateStroke2Page(wxWindow * book);
+  wxPanel *CreateFill2Page(wxWindow * book);
+  wxPanel *CreatePreviewPage(wxWindow * book);
+  void CreateButtons();
+  bool FinalValidityCheck();
+  bool RetrieveMainPage();
+  bool RetrieveStroke1Page(bool check = true);
+  bool RetrieveFill1Page(bool check = true);
+  bool RetrieveStroke2Page(bool check = true);
+  bool RetrieveFill2Page(bool check = true);
+  bool RetrievePreviewPage();
+  void UpdateMainPage();
+  void UpdateStroke1Page();
+  void UpdateFill1Page();
+  void UpdateStroke2Page();
+  void UpdateFill2Page();
+  void UpdatePreviewPage();
+  char *DoCreateSymbolizerXML();
+  char *DoCreateFeatureTypeXML();
+  void DrawPreview(int horz, int vert);
+  bool DoParseDashArray(wxString & str, int which);
+  void NormalizedDashArray(wxString & str, int which, char delimiter = ',');
+  void PreparePolygonPath(void *ctx, double perpendicular_offset,
+                          double displacement_x, double displacement_y);
+  wxBitmap PreviewBackBitmap;
+public:
+    SimplePolygonSymbolizerDialog();
+  bool Create(MyFrame * parent);
+    virtual ~ SimplePolygonSymbolizerDialog();
+  void OnQuit(wxCommandEvent & event);
+  void OnInsert(wxCommandEvent & event);
+  void OnExport(wxCommandEvent & event);
+  void OnCopy(wxCommandEvent & event);
+  void OnPageChanging(wxNotebookEvent & event);
+  void OnPageChanged(wxNotebookEvent & event);
+  void OnCmdUomChanged(wxCommandEvent & event);
+  void OnCmdScaleChanged(wxCommandEvent & event);
+  void OnCmdStroke1TypeChanged(wxCommandEvent & event);
+  void OnCmdFill1TypeChanged(wxCommandEvent & event);
+  void OnCmdStroke2TypeChanged(wxCommandEvent & event);
+  void OnCmdFill2TypeChanged(wxCommandEvent & event);
+  void OnCmdColor1Changed(wxCommandEvent & event);
+  void OnCmdColor2Changed(wxCommandEvent & event);
+  void OnCmdColor3Changed(wxCommandEvent & event);
+  void OnCmdColor4Changed(wxCommandEvent & event);
+  void OnCmdColor1Picker(wxCommandEvent & event);
+  void OnCmdColor2Picker(wxCommandEvent & event);
+  void OnCmdColor3Picker(wxCommandEvent & event);
+  void OnCmdColor4Picker(wxCommandEvent & event);
+  void OnCmdFill1ReplacementChanged(wxCommandEvent & event);
+  void OnCmdStroke1ReplacementChanged(wxCommandEvent & event);
+  void OnCmdFill2ReplacementChanged(wxCommandEvent & event);
+  void OnCmdStroke2ReplacementChanged(wxCommandEvent & event);
+  void OnCmdLineJoin1Changed(wxCommandEvent & event);
+  void OnCmdLineJoin2Changed(wxCommandEvent & event);
+  void OnCmdLineCap1Changed(wxCommandEvent & event);
+  void OnCmdLineCap2Changed(wxCommandEvent & event);
+  void OnCmdStroke1Changed(wxCommandEvent & event);
+  void OnCmdStroke2Changed(wxCommandEvent & event);
+  void OnCmdFill1Changed(wxCommandEvent & event);
+  void OnCmdFill2Changed(wxCommandEvent & event);
+  void OnCmdFill1EnableReplacementChanged(wxCommandEvent & event);
+  void OnCmdStroke1EnableReplacementChanged(wxCommandEvent & event);
+  void OnCmdFill2EnableReplacementChanged(wxCommandEvent & event);
+  void OnCmdStroke2EnableReplacementChanged(wxCommandEvent & event);
+  void OnCmdPolygon2Changed(wxCommandEvent & event);
+  void OnCmdBackgroundChanged(wxCommandEvent & event);
+};
+
+class SimplePointSymbolizerDialog:public wxPropertySheetDialog
+{
+//
+// a dialog for creating an SLD/SE PointSymbolizer 
+// of the simple type
+//
+private:
+  MyFrame * MainFrame;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  unsigned char Uom;
+  bool MinScale;
+  bool MaxScale;
+  double MinScaleDenominator;
+  double MaxScaleDenominator;
+  double Opacity;
+  double Size;
+  double Rotation;
+  double AnchorPointX;
+  double AnchorPointY;
+  double DisplacementX;
+  double DisplacementY;
+  bool OnlyRescaleSVG;
+  bool HasGraphic;
+  wxString XLinkHref;
+  wxString MimeType;
+  bool EnableColorReplacement;
+  wxString ColorReplacement;
+  int WellKnownMark;
+  bool EnableFill;
+  bool EnableStroke;
+  wxString FillColor;
+  wxString StrokeColor;
+  double StrokeWidth;
+  int StrokeLineJoin;
+  int StrokeLineCap;
+  int StrokeDashCount;
+  double *StrokeDashArray;
+  double StrokeDashOffset;
+  ExternalGraphicList *List;
+  wxGrid *GridCtrl;
+  unsigned char PreviewBackground;
+  bool Crosshair;
+  wxPanel *CreateMainPage(wxWindow * book);
+  wxPanel *CreatePositionPage(wxWindow * book);
+  wxPanel *CreateGraphicPage(wxWindow * book);
+  wxPanel *CreateMarkPage(wxWindow * book);
+  wxPanel *CreatePreviewPage(wxWindow * book);
+  void CreateButtons();
+  bool FinalValidityCheck();
+  bool RetrieveMainPage();
+  bool RetrievePositionPage(bool check = true);
+  bool RetrieveGraphicPage(bool check = true);
+  bool RetrieveMarkPage(bool check = true);
+  bool RetrievePreviewPage();
+  void UpdateMainPage();
+  void UpdatePositionPage();
+  void UpdateGraphicPage();
+  void UpdateMarkPage();
+  void UpdatePreviewPage();
+  char *DoCreateSymbolizerXML();
+  char *DoCreateFeatureTypeXML();
+  void DrawPreview(int horz, int vert);
+  bool DoParseDashArray(wxString & str);
+  void NormalizedDashArray(wxString & str, char delimiter = ',');
+  wxBitmap PreviewBackBitmap;
+public:
+    SimplePointSymbolizerDialog();
+  bool Create(MyFrame * parent);
+    virtual ~ SimplePointSymbolizerDialog();
+  void OnQuit(wxCommandEvent & event);
+  void OnInsert(wxCommandEvent & event);
+  void OnExport(wxCommandEvent & event);
+  void OnCopy(wxCommandEvent & event);
+  void OnPageChanging(wxNotebookEvent & event);
+  void OnPageChanged(wxNotebookEvent & event);
+  void OnCmdUomChanged(wxCommandEvent & event);
+  void OnCmdScaleChanged(wxCommandEvent & event);
+  void OnCmdTypeChanged(wxCommandEvent & event);
+  void OnCmdMarkChanged(wxCommandEvent & event);
+  void OnCmdStrokeChanged(wxCommandEvent & event);
+  void OnCmdFillChanged(wxCommandEvent & event);
+  void OnCmdColorFillChanged(wxCommandEvent & event);
+  void OnCmdColorStrokeChanged(wxCommandEvent & event);
+  void OnCmdColorReplacementChanged(wxCommandEvent & event);
+  void OnCmdColorFillPicker(wxCommandEvent & event);
+  void OnCmdColorStrokePicker(wxCommandEvent & event);
+  void OnCmdColorReplacementPicker(wxCommandEvent & event);
+  void OnCmdOnlyRescaleSVG(wxCommandEvent & event);
+  void OnCmdLineJoinChanged(wxCommandEvent & event);
+  void OnCmdLineCapChanged(wxCommandEvent & event);
+  void OnCmdEnableReplacementChanged(wxCommandEvent & event);
+  void OnCmdBackgroundChanged(wxCommandEvent & event);
+  void OnCmdCrosshairChanged(wxCommandEvent & event);
+};
+
+class SimpleTextSymbolizerDialog:public wxPropertySheetDialog
+{
+//
+// a dialog for creating an SLD/SE TextSymbolizer 
+// of the simple type
+//
+private:
+  MyFrame * MainFrame;
+  wxString Name;
+  wxString Title;
+  wxString Abstract;
+  unsigned char Uom;
+  bool MinScale;
+  bool MaxScale;
+  double MinScaleDenominator;
+  double MaxScaleDenominator;
+  wxString Label;
+  wxString FontFamily;
+  int FontStyle;
+  int FontWeight;
+  double FontSize;
+  bool PointPlacement;
+  double Rotation;
+  double AnchorPointX;
+  double AnchorPointY;
+  double DisplacementX;
+  double DisplacementY;
+  double PerpendicularOffset;
+  bool IsRepeated;
+  double InitialGap;
+  double Gap;
+  bool IsAligned;
+  bool GeneralizeLine;
+  bool HasHalo;
+  double HaloRadius;
+  wxString HaloColor;
+  double HaloOpacity;
+  wxString FillColor;
+  double FillOpacity;
+  TextFontList *List;
+  wxGrid *GridCtrl;
+  unsigned char PreviewBackground;
+  bool Crosshair;
+  bool ReferenceLine;
+  wxPanel *CreateMainPage(wxWindow * book);
+  wxPanel *CreateFontPage(wxWindow * book);
+  wxPanel *CreatePlacementPage(wxWindow * book);
+  wxPanel *CreatePreviewPage(wxWindow * book);
+  void CreateButtons();
+  bool FinalValidityCheck();
+  bool RetrieveMainPage();
+  bool RetrieveFontPage(bool check = true);
+  bool RetrievePlacementPage(bool check = true);
+  bool RetrievePreviewPage();
+  void UpdateMainPage();
+  void UpdateFontPage();
+  void UpdatePlacementPage();
+  void UpdatePreviewPage();
+  char *DoCreateSymbolizerXML();
+  char *DoCreateFeatureTypeXML();
+  gaiaGeomCollPtr PrepareLinestring(double perpendicular_offset);
+  void PrepareLinestringPath(void *ctx, double perpendicular_offset);
+  void GetLineCenterPoint(double perpendicular_offset, double *x, double *y);
+  void CreateLineArray(double perpendicular_offset, int *points, double **x,
+                       double **y, int generalize);
+  void DrawPreview(int horz, int vert);
+  wxBitmap PreviewBackBitmap;
+public:
+    SimpleTextSymbolizerDialog();
+  bool Create(MyFrame * parent);
+    virtual ~ SimpleTextSymbolizerDialog();
+  void OnQuit(wxCommandEvent & event);
+  void OnInsert(wxCommandEvent & event);
+  void OnExport(wxCommandEvent & event);
+  void OnCopy(wxCommandEvent & event);
+  void OnPageChanging(wxNotebookEvent & event);
+  void OnPageChanged(wxNotebookEvent & event);
+  void OnCmdUomChanged(wxCommandEvent & event);
+  void OnCmdScaleChanged(wxCommandEvent & event);
+  void OnCmdTypeChanged(wxCommandEvent & event);
+  void OnCmdColorFillChanged(wxCommandEvent & event);
+  void OnCmdHaloEnableChanged(wxCommandEvent & event);
+  void OnCmdColorHaloChanged(wxCommandEvent & event);
+  void OnCmdColorFillPicker(wxCommandEvent & event);
+  void OnCmdColorHaloPicker(wxCommandEvent & event);
+  void OnCmdIsRepeatedChanged(wxCommandEvent & event);
+  void OnCmdIsAlignedChanged(wxCommandEvent & event);
+  void OnCmdGeneralizeLineChanged(wxCommandEvent & event);
+  void OnCmdBackgroundChanged(wxCommandEvent & event);
+  void OnCmdCrosshairChanged(wxCommandEvent & event);
+  void OnCmdReferenceLineChanged(wxCommandEvent & event);
+};
+
+class ComposerMainPage:public wxPanel
+{
+//
+// first page used by Query/View COMPOSER
+//
+private:
+  class ComposerDialog * Parent;
+  wxCheckBox *Table2Ctrl;
+  wxComboBox *Table1NameCtrl;
+  wxComboBox *Table2NameCtrl;
+  wxTextCtrl *Table1AliasCtrl;
+  wxTextCtrl *Table2AliasCtrl;
+  wxListBox *Table1ColumnsCtrl;
+  wxListBox *Table2ColumnsCtrl;
+  wxRadioBox *JoinModeCtrl;
+  wxCheckBox *Match2Ctrl;
+  wxCheckBox *Match3Ctrl;
+  wxComboBox *Match1Table1Ctrl;
+  wxComboBox *Match1Table2Ctrl;
+  wxComboBox *Match2Table1Ctrl;
+  wxComboBox *Match2Table2Ctrl;
+  wxComboBox *Match3Table1Ctrl;
+  wxComboBox *Match3Table2Ctrl;
+public:
+    ComposerMainPage()
+  {;
+  }
+  bool Create(ComposerDialog * parent);
+  virtual ~ ComposerMainPage()
   {;
   }
   void CreateControls();
@@ -5800,6 +9685,10 @@ public:
   void SelectGeometryColumn();
   void UpdateSqlSample();
   void PrepareSqlTriggers();
+  bool GetCurrentlySelectedTable(wxString & table_name)
+  {
+    return MainFrame->GetCurrentlySelectedTable(table_name);
+  }
   void OnOk(wxCommandEvent & event);
 };
 
diff --git a/Dialogs.cpp b/Dialogs.cpp
index b1175af..e033667 100644
--- a/Dialogs.cpp
+++ b/Dialogs.cpp
@@ -27,6 +27,7 @@
 
 #include "wx/spinctrl.h"
 #include "wx/listctrl.h"
+#include "wx/tokenzr.h"
 #include "wx/html/htmlwin.h"
 
 bool SanitizeAllGeometriesDialog::Create(MyFrame * parent)
@@ -317,7 +318,8 @@ void SanitizeGeometryDialog::OnYes(wxCommandEvent & WXUNUSED(event))
 }
 
 bool GisLayerAuthDialog::Create(MyFrame * parent, wxString & table,
-                                wxString & geom, bool rdOnly, bool hidden)
+                                wxString & geom, bool rdOnly, bool hidden,
+                                bool is_table)
 {
 //
 // creating the dialog
@@ -327,6 +329,7 @@ bool GisLayerAuthDialog::Create(MyFrame * parent, wxString & table,
   Geometry = geom;
   ReadOnly = rdOnly;
   Hidden = hidden;
+  IsTable = is_table;
   if (Hidden == true)
     ReadOnly = false;
   if (wxDialog::Create(parent, wxID_ANY, wxT("GIS Layer authorizations")) ==
@@ -407,6 +410,8 @@ void GisLayerAuthDialog::CreateControls()
     rdOnlyBox->SetSelection(0);
   if (Hidden == true)
     rdOnlyBox->Enable(false);
+  if (!IsTable)
+    rdOnlyBox->Enable(false);
 // OK - CANCEL buttons
   wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
   boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
@@ -452,6 +457,8 @@ void GisLayerAuthDialog::OnHiddenChanged(wxCommandEvent & WXUNUSED(event))
         rdOnlyCtrl->SetSelection(1);
       rdOnlyCtrl->Enable(true);
     }
+  if (!IsTable)
+    rdOnlyCtrl->Enable(false);
 }
 
 void GisLayerAuthDialog::OnReadOnlyChanged(wxCommandEvent & WXUNUSED(event))
@@ -489,6 +496,7 @@ bool VirtualShpDialog::Create(MyFrame * parent, wxString & path,
   Path = path;
   Table = table;
   Default = defCs;
+  TextDates = false;
   if (wxDialog::Create(parent, wxID_ANY, wxT("Creating Virtual Shapefile")) ==
       false)
     return false;
@@ -562,6 +570,21 @@ void VirtualShpDialog::CreateControls()
   if (idSel != wxNOT_FOUND)
     charsetCtrl->SetSelection(idSel);
   charsetSizer->Add(charsetCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// DBF dates interpreatation
+  wxBoxSizer *dbfDatesBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(dbfDatesBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxString dbf_dates[2];
+  dbf_dates[0] = wxT("as Julian Day numbers");
+  dbf_dates[1] = wxT("as PlainText strings");
+  wxRadioBox *dbf_dates_sel = new wxRadioBox(this, ID_VIRTSHP_TEXTDATES,
+                                             wxT
+                                             ("interpretation of &DBF DATE values"),
+                                             wxDefaultPosition,
+                                             wxDefaultSize, 2,
+                                             dbf_dates, 2,
+                                             wxRA_SPECIFY_COLS);
+  dbf_dates_sel->SetSelection(0);
+  dbfDatesBox->Add(dbf_dates_sel, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
 // OK - CANCEL buttons
   wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
   boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
@@ -572,6 +595,20 @@ void VirtualShpDialog::CreateControls()
 // appends event handler for OK button
   Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
           (wxObjectEventFunction) & VirtualShpDialog::OnOk);
+  Connect(ID_VIRTSHP_TEXTDATES, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) & VirtualShpDialog::OnTextDates);
+}
+
+void VirtualShpDialog::OnTextDates(wxCommandEvent & WXUNUSED(event))
+{
+//
+// the mode of user defined DBF TextDates changed
+//
+  wxRadioBox *radioCtrl = (wxRadioBox *) FindWindow(ID_VIRTSHP_TEXTDATES);
+  if (radioCtrl->GetSelection() == 0)
+    TextDates = false;
+  else
+    TextDates = true;
 }
 
 void VirtualShpDialog::OnOk(wxCommandEvent & WXUNUSED(event))
@@ -928,6 +965,7 @@ bool VirtualDbfDialog::Create(MyFrame * parent, wxString & path,
   Path = path;
   Table = table;
   Default = defCs;
+  TextDates = false;
   if (wxDialog::Create(parent, wxID_ANY, wxT("Creating Virtual DBF")) == false)
     return false;
 // populates individual controls
@@ -989,6 +1027,21 @@ void VirtualDbfDialog::CreateControls()
   if (idSel != wxNOT_FOUND)
     charsetCtrl->SetSelection(idSel);
   charsetSizer->Add(charsetCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// DBF dates interpreatation
+  wxBoxSizer *dbfDatesBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(dbfDatesBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxString dbf_dates[2];
+  dbf_dates[0] = wxT("as Julian Day numbers");
+  dbf_dates[1] = wxT("as PlainText strings");
+  wxRadioBox *dbf_dates_sel = new wxRadioBox(this, ID_VIRTDBF_TEXTDATES,
+                                             wxT
+                                             ("interpretation of &DBF DATE values"),
+                                             wxDefaultPosition,
+                                             wxDefaultSize, 2,
+                                             dbf_dates, 2,
+                                             wxRA_SPECIFY_COLS);
+  dbf_dates_sel->SetSelection(0);
+  dbfDatesBox->Add(dbf_dates_sel, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
 // OK - CANCEL buttons
   wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
   boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
@@ -999,6 +1052,20 @@ void VirtualDbfDialog::CreateControls()
 // appends event handler for OK button
   Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
           (wxObjectEventFunction) & VirtualDbfDialog::OnOk);
+  Connect(ID_VIRTDBF_TEXTDATES, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) & VirtualDbfDialog::OnTextDates);
+}
+
+void VirtualDbfDialog::OnTextDates(wxCommandEvent & WXUNUSED(event))
+{
+//
+// the mode of user defined DBF TextDates changed
+//
+  wxRadioBox *radioCtrl = (wxRadioBox *) FindWindow(ID_VIRTDBF_TEXTDATES);
+  if (radioCtrl->GetSelection() == 0)
+    TextDates = false;
+  else
+    TextDates = true;
 }
 
 void VirtualDbfDialog::OnOk(wxCommandEvent & WXUNUSED(event))
@@ -1891,6 +1958,7 @@ bool LoadDbfDialog::Create(MyFrame * parent, wxString & path, wxString & table,
   PKCount = 0;
   PKFields = NULL;
   PKFieldsEx = NULL;
+  TextDates = false;
   LoadPKFields();
   if (wxDialog::Create(parent, wxID_ANY, wxT("Load DBF")) == false)
     return false;
@@ -1978,6 +2046,21 @@ void LoadDbfDialog::CreateControls()
                    wxSize(180, 21), 0, NULL, wxCB_DROPDOWN | wxCB_READONLY);
   pkeyList->Enable(false);
   gPKeySizer->Add(pkeyList, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// DBF dates interpreatation
+  wxBoxSizer *dbfDatesBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(dbfDatesBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxString dbf_dates[2];
+  dbf_dates[0] = wxT("as Julian Day numbers");
+  dbf_dates[1] = wxT("as PlainText strings");
+  wxRadioBox *dbf_dates_sel = new wxRadioBox(this, ID_LDDBF_TEXTDATES,
+                                             wxT
+                                             ("interpretation of &DBF DATE values"),
+                                             wxDefaultPosition,
+                                             wxDefaultSize, 2,
+                                             dbf_dates, 2,
+                                             wxRA_SPECIFY_COLS);
+  dbf_dates_sel->SetSelection(0);
+  dbfDatesBox->Add(dbf_dates_sel, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
 // OK - CANCEL buttons
   wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
   boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
@@ -1990,6 +2073,8 @@ void LoadDbfDialog::CreateControls()
           (wxObjectEventFunction) & LoadDbfDialog::OnOk);
   Connect(ID_LDDBF_USER_PKEY, wxEVT_COMMAND_RADIOBOX_SELECTED,
           (wxObjectEventFunction) & LoadDbfDialog::OnUserPKey);
+  Connect(ID_LDDBF_TEXTDATES, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) & LoadDbfDialog::OnTextDates);
 }
 
 
@@ -2117,6 +2202,17 @@ void LoadDbfDialog::OnUserPKey(wxCommandEvent & WXUNUSED(event))
     }
 }
 
+void LoadDbfDialog::OnTextDates(wxCommandEvent & WXUNUSED(event))
+{
+//
+// the mode of user defined DBF TextDates changed
+//
+  wxRadioBox *radioCtrl = (wxRadioBox *) FindWindow(ID_LDDBF_TEXTDATES);
+  if (radioCtrl->GetSelection() == 0)
+    TextDates = false;
+  else
+    TextDates = true;
+}
 
 void LoadDbfDialog::OnOk(wxCommandEvent & WXUNUSED(event))
 {
@@ -2198,6 +2294,7 @@ bool LoadShpDialog::Create(MyFrame * parent, wxString & path, wxString & table,
   PKCount = 0;
   PKFields = NULL;
   PKFieldsEx = NULL;
+  TextDates = false;
   LoadPKFields();
   if (wxDialog::Create(parent, wxID_ANY, wxT("Load Shapefile")) == false)
     return false;
@@ -2349,6 +2446,21 @@ void LoadShpDialog::CreateControls()
                    wxSize(180, 21), 0, NULL, wxCB_DROPDOWN | wxCB_READONLY);
   pkeyList->Enable(false);
   gPKeySizer->Add(pkeyList, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// DBF dates interpreatation
+  wxBoxSizer *dbfDatesBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(dbfDatesBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxString dbf_dates[2];
+  dbf_dates[0] = wxT("as Julian Day numbers");
+  dbf_dates[1] = wxT("as PlainText strings");
+  wxRadioBox *dbf_dates_sel = new wxRadioBox(this, ID_LDSHP_TEXTDATES,
+                                             wxT
+                                             ("interpretation of &DBF DATE values"),
+                                             wxDefaultPosition,
+                                             wxDefaultSize, 2,
+                                             dbf_dates, 2,
+                                             wxRA_SPECIFY_COLS);
+  dbf_dates_sel->SetSelection(0);
+  dbfDatesBox->Add(dbf_dates_sel, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
 // OK - CANCEL buttons
   wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
   boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
@@ -2363,6 +2475,8 @@ void LoadShpDialog::CreateControls()
           (wxObjectEventFunction) & LoadShpDialog::OnUserGType);
   Connect(ID_LDSHP_USER_PKEY, wxEVT_COMMAND_RADIOBOX_SELECTED,
           (wxObjectEventFunction) & LoadShpDialog::OnUserPKey);
+  Connect(ID_LDSHP_TEXTDATES, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) & LoadShpDialog::OnTextDates);
 }
 
 void LoadShpDialog::LoadPKFields()
@@ -2542,6 +2656,18 @@ void LoadShpDialog::OnUserPKey(wxCommandEvent & WXUNUSED(event))
     }
 }
 
+void LoadShpDialog::OnTextDates(wxCommandEvent & WXUNUSED(event))
+{
+//
+// the mode of user defined DBF TextDates changed
+//
+  wxRadioBox *radioCtrl = (wxRadioBox *) FindWindow(ID_LDSHP_TEXTDATES);
+  if (radioCtrl->GetSelection() == 0)
+    TextDates = false;
+  else
+    TextDates = true;
+}
+
 void LoadShpDialog::OnOk(wxCommandEvent & WXUNUSED(event))
 {
 //
@@ -3934,15 +4060,6 @@ bool HelpDialog::Create(MyFrame * parent)
   return true;
 }
 
-void HelpDialog::OnClose(wxCloseEvent & WXUNUSED(event))
-{
-//
-// this window has been closed
-//
-  MainFrame->CloseHelpPane();
-  Destroy();
-}
-
 void HelpDialog::CreateControls()
 {
 //
@@ -3958,8 +4075,15 @@ void HelpDialog::CreateControls()
   wxString html;
   MainFrame->GetHelp(html);
   helpWin->SetPage(html);
-  topSizer->Add(helpWin, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  boxSizer->Add(helpWin, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// QUIT button
+  wxBoxSizer *quitBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(quitBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *quit = new wxButton(this, wxID_CANCEL, wxT("&Quit"));
+  quitBox->Add(quit, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
 // setting up the event handlers
+  Connect(wxID_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & HelpDialog::OnCancel);
   Connect(wxID_ANY, wxEVT_SIZE, (wxObjectEventFunction) & HelpDialog::OnSize);
 }
 
@@ -3970,7 +4094,30 @@ void HelpDialog::OnSize(wxSizeEvent & WXUNUSED(event))
 //
   wxSize sz = GetClientSize();
   wxHtmlWindow *helpWin = (wxHtmlWindow *) FindWindow(ID_HELP_HTML);
-  helpWin->SetSize(sz.GetWidth() - 6, sz.GetHeight() - 6);
+  wxButton *quit = (wxButton *) FindWindow(wxID_CANCEL);
+  wxSize btnSz = quit->GetSize();
+  helpWin->SetSize(sz.GetWidth() - 6, sz.GetHeight() - 20 - btnSz.GetHeight());
+  int x = (sz.GetWidth() - btnSz.GetWidth()) / 2;
+  int y = sz.GetHeight() - 6 - btnSz.GetHeight();
+  quit->SetSize(x, y, btnSz.GetWidth(), btnSz.GetHeight());
+}
+
+void HelpDialog::OnClose(wxCloseEvent & WXUNUSED(event))
+{
+//
+// this window has been closed
+//
+  MainFrame->CloseHelpPane();
+  Destroy();
+}
+
+void HelpDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  MainFrame->CloseHelpPane();
+  Destroy();
 }
 
 bool NetworkDialog::Create(MyFrame * parent)
@@ -3981,6 +4128,7 @@ bool NetworkDialog::Create(MyFrame * parent)
   MainFrame = parent;
   FromColumn = wxT("");
   ToColumn = wxT("");
+  NoGeometry = false;
   GeomColumn = wxT("");
   GeomLength = true;
   CostColumn = wxT("");
@@ -3991,6 +4139,8 @@ bool NetworkDialog::Create(MyFrame * parent)
   OneWayFromTo = wxT("");
   OneWayToFrom = wxT("");
   NameColumn = wxT("");
+  DataTable = wxT("");
+  VirtualTable = wxT("");
   if (wxDialog::Create(parent, wxID_ANY, wxT("Build Network")) == false)
     return false;
 // populates individual controls
@@ -4011,9 +4161,9 @@ void NetworkDialog::CreateControls()
   wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
   this->SetSizer(topSizer);
   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
-  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
   wxBoxSizer *row0Sizer = new wxBoxSizer(wxHORIZONTAL);
-  boxSizer->Add(row0Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  boxSizer->Add(row0Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
 // the Main TABLE
   wxBoxSizer *tableSizer = new wxBoxSizer(wxHORIZONTAL);
   row0Sizer->Add(tableSizer, 0, wxALIGN_CENTRE_VERTICAL | wxALL, 0);
@@ -4022,15 +4172,24 @@ void NetworkDialog::CreateControls()
                                           wxDefaultPosition,
                                           wxDefaultSize);
   wxBoxSizer *tableNameSizer = new wxStaticBoxSizer(tableBox, wxVERTICAL);
-  tableSizer->Add(tableNameSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  tableSizer->Add(tableNameSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
   int nTables;
   wxString *tables = MainFrame->GetTables(&nTables);
-  wxSize size = wxSize(150, 300);
+  wxSize size = wxSize(160, 360);
   wxListBox *tableCtrl = new wxListBox();
-  tableNameSizer->Add(tableCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
   tableCtrl->Create(this, ID_NET_TABLE, wxDefaultPosition, size, nTables,
                     tables, wxLB_SINGLE | wxLB_HSCROLL);
-  size = wxSize(100, 80);
+  tableNameSizer->Add(tableCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  size = wxSize(140, 80);
+  wxSize size2 = wxSize(140, 60);
+  wxString table;
+  if (MainFrame->GetCurrentlySelectedTable(table) == true)
+    {
+      // automatically selecting the current table
+      int sel = tableCtrl->FindString(table);
+      if (sel != wxNOT_FOUND)
+        tableCtrl->SetSelection(sel);
+    }
 // the NodeFrom COLUMN
   wxBoxSizer *netSizer = new wxBoxSizer(wxHORIZONTAL);
   row0Sizer->Add(netSizer, 0, wxALIGN_RIGHT | wxALL, 0);
@@ -4069,19 +4228,25 @@ void NetworkDialog::CreateControls()
                                     0, NULL, wxLB_SINGLE | wxLB_HSCROLL);
   toCtrl->Enable(false);
   toColSizer->Add(toCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+
 // the Geometry COLUMN
   wxBoxSizer *geoSizer = new wxBoxSizer(wxHORIZONTAL);
-  row1Sizer->Add(geoSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  row1Sizer->Add(geoSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
   wxStaticBox *geoBox = new wxStaticBox(this, wxID_STATIC,
                                         wxT("Geometry Column"),
                                         wxDefaultPosition,
                                         wxDefaultSize);
   wxBoxSizer *geoColSizer = new wxStaticBoxSizer(geoBox, wxVERTICAL);
   toSizer->Add(geoColSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 1);
+// NoGeometry
+  wxCheckBox *geomEnable =
+    new wxCheckBox(this, ID_NET_NO_GEOM, wxT("&NoGeometry"));
+  geomEnable->SetValue(false);
+  geoColSizer->Add(geomEnable, 0, wxALIGN_LEFT | wxALL, 1);
+// the Geometry COLUMN
   wxListBox *geoCtrl = new wxListBox(this, ID_NET_GEOM,
-                                     wxDefaultPosition, size,
+                                     wxDefaultPosition, size2,
                                      0, NULL, wxLB_SINGLE | wxLB_HSCROLL);
-  geoCtrl->Enable(false);
   geoColSizer->Add(geoCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
 // UNIDIRECTIONAL / BIDIRECTIONAL
   wxBoxSizer *row2Sizer = new wxBoxSizer(wxHORIZONTAL);
@@ -4159,7 +4324,7 @@ void NetworkDialog::CreateControls()
 // OneWay Enable
   wxCheckBox *oneWayEnable =
     new wxCheckBox(this, ID_NET_ONEWAY, wxT("Enable &OneWays"));
-  colWaySizer->Add(oneWayEnable, 0, wxALIGN_LEFT | wxALL, 5);
+  colWaySizer->Add(oneWayEnable, 0, wxALIGN_LEFT | wxALL, 1);
 // the OneWay FromTo COLUMN
   wxBoxSizer *fromToSizer = new wxBoxSizer(wxHORIZONTAL);
   colWaySizer->Add(fromToSizer, 0, wxALIGN_LEFT | wxALL, 0);
@@ -4198,13 +4363,37 @@ void NetworkDialog::CreateControls()
 // Name Enable
   wxCheckBox *nameEnable =
     new wxCheckBox(this, ID_NET_NAME_ENABLE, wxT("Enable &Name"));
-  nameColSizer->Add(nameEnable, 0, wxALIGN_LEFT | wxALL, 5);
+  nameColSizer->Add(nameEnable, 0, wxALIGN_LEFT | wxALL, 1);
 // the Name COLUMN
   wxListBox *nameCtrl = new wxListBox(this, ID_NET_NAME,
                                       wxDefaultPosition, size,
                                       0, NULL, wxLB_SINGLE | wxLB_HSCROLL);
   nameCtrl->Enable(false);
   nameColSizer->Add(nameCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// output tables
+  wxBoxSizer *outSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(outSizer, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 0);
+  wxStaticBox *outTablesBox = new wxStaticBox(this, wxID_STATIC,
+                                              wxT("Output Tables"),
+                                              wxDefaultPosition,
+                                              wxDefaultSize);
+  wxBoxSizer *outTablesSizer = new wxStaticBoxSizer(outTablesBox, wxHORIZONTAL);
+  outSizer->Add(outTablesSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *dataTableLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&binary data Table:"));
+  outTablesSizer->Add(dataTableLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+  wxTextCtrl *dataTableCtrl = new wxTextCtrl(this, ID_NET_DATA, wxT(""),
+                                             wxDefaultPosition, wxSize(150,
+                                                                       22));
+  outTablesSizer->Add(dataTableCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  outTablesSizer->AddSpacer(15);
+  wxStaticText *virtualTableLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&VirtualNetwork Table:"));
+  outTablesSizer->Add(virtualTableLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+  wxTextCtrl *virtualTableCtrl = new wxTextCtrl(this, ID_NET_VIRTUAL, wxT(""),
+                                                wxDefaultPosition, wxSize(150,
+                                                                          22));
+  outTablesSizer->Add(virtualTableCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
 // OK - CANCEL buttons
   wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
   boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
@@ -4226,6 +4415,8 @@ void NetworkDialog::CreateControls()
           (wxObjectEventFunction) & NetworkDialog::OnOneWay);
   Connect(ID_NET_NAME_ENABLE, wxEVT_COMMAND_CHECKBOX_CLICKED,
           (wxObjectEventFunction) & NetworkDialog::OnNameEnabled);
+  Connect(ID_NET_NO_GEOM, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) & NetworkDialog::OnNoGeometry);
 }
 
 void NetworkDialog::OnTable(wxCommandEvent & WXUNUSED(event))
@@ -4235,6 +4426,12 @@ void NetworkDialog::OnTable(wxCommandEvent & WXUNUSED(event))
 //
   wxListBox *tableCtrl = (wxListBox *) FindWindow(ID_NET_TABLE);
   TableName = tableCtrl->GetStringSelection();
+  wxTextCtrl *dataTableCtrl = (wxTextCtrl *) FindWindow(ID_NET_DATA);
+  wxString data_table = TableName + wxT("_net_data");
+  dataTableCtrl->SetValue(data_table);
+  wxTextCtrl *virtualTableCtrl = (wxTextCtrl *) FindWindow(ID_NET_VIRTUAL);
+  wxString net_table = TableName + wxT("_net");
+  virtualTableCtrl->SetValue(net_table);
   int n_cols;
   wxString *columns = MainFrame->GetColumnNames(TableName, &n_cols);
   wxListBox *fromCtrl = (wxListBox *) FindWindow(ID_NET_FROM);
@@ -4378,6 +4575,41 @@ void NetworkDialog::OnNameEnabled(wxCommandEvent & WXUNUSED(event))
     }
 }
 
+void NetworkDialog::OnNoGeometry(wxCommandEvent & WXUNUSED(event))
+{
+//
+// NoGeometry check box
+//
+  wxCheckBox *noGeom = (wxCheckBox *) FindWindow(ID_NET_NO_GEOM);
+  wxListBox *geomCtrl = (wxListBox *) FindWindow(ID_NET_GEOM);
+  wxRadioBox *aStarSel = (wxRadioBox *) FindWindow(ID_NET_A_STAR);
+  wxRadioBox *costSel = (wxRadioBox *) FindWindow(ID_NET_LENGTH);
+  wxListBox *costCtrl = (wxListBox *) FindWindow(ID_NET_COST);
+  if (NoGeometry == true)
+    {
+      NoGeometry = false;
+      noGeom->SetValue(false);
+      geomCtrl->Enable(true);
+      aStarSel->SetSelection(0);
+      aStarSel->Enable(true);
+      costSel->Enable(true);
+      GeomLength = true;
+      costSel->SetSelection(0);
+      costCtrl->Enable(false);
+  } else
+    {
+      NoGeometry = true;
+      noGeom->SetValue(true);
+      geomCtrl->Enable(false);
+      aStarSel->SetSelection(1);
+      aStarSel->Enable(false);
+      costSel->Enable(false);
+      GeomLength = false;
+      costSel->SetSelection(1);
+      costCtrl->Enable(true);
+    }
+}
+
 void NetworkDialog::OnOk(wxCommandEvent & WXUNUSED(event))
 {
 //
@@ -4407,17 +4639,30 @@ void NetworkDialog::OnOk(wxCommandEvent & WXUNUSED(event))
                    wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
       return;
     }
-  wxListBox *geomCtrl = (wxListBox *) FindWindow(ID_NET_GEOM);
-  GeomColumn = geomCtrl->GetStringSelection();
-  if (GeomColumn.Len() < 1)
+  if (NoGeometry == false)
     {
-      wxMessageBox(wxT("You must select some 'Geometry' COLUMN !!!"),
-                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
-      return;
-    }
-  if (GeomLength == true)
-    CostColumn = wxT("");
-  else
+      wxListBox *geomCtrl = (wxListBox *) FindWindow(ID_NET_GEOM);
+      GeomColumn = geomCtrl->GetStringSelection();
+      if (GeomColumn.Len() < 1)
+        {
+          wxMessageBox(wxT("You must select some 'Geometry' COLUMN !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return;
+        }
+      if (GeomLength == true)
+        CostColumn = wxT("");
+      else
+        {
+          wxListBox *costCtrl = (wxListBox *) FindWindow(ID_NET_COST);
+          CostColumn = costCtrl->GetStringSelection();
+          if (CostColumn.Len() < 1)
+            {
+              wxMessageBox(wxT("You must select some 'Cost' COLUMN !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return;
+            }
+        }
+  } else
     {
       wxListBox *costCtrl = (wxListBox *) FindWindow(ID_NET_COST);
       CostColumn = costCtrl->GetStringSelection();
@@ -4468,6 +4713,31 @@ void NetworkDialog::OnOk(wxCommandEvent & WXUNUSED(event))
     AStarSupported = false;
   else
     AStarSupported = true;
+  wxTextCtrl *dataTableCtrl = (wxTextCtrl *) FindWindow(ID_NET_DATA);
+  DataTable = dataTableCtrl->GetValue();
+  if (DataTable.Len() < 1)
+    {
+      wxMessageBox(wxT
+                   ("You must specify some 'binary data' Table to be created !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  wxTextCtrl *virtualTableCtrl = (wxTextCtrl *) FindWindow(ID_NET_VIRTUAL);
+  VirtualTable = virtualTableCtrl->GetValue();
+  if (VirtualTable.Len() < 1)
+    {
+      wxMessageBox(wxT
+                   ("You must specify some VirtualNetwork Table to be created !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (DataTable.CmpNoCase(VirtualTable) == 0)
+    {
+      wxMessageBox(wxT
+                   ("'binary data' and VirtualNetwork Tables must have different names !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
   wxDialog::EndModal(wxID_OK);
 }
 
@@ -5522,7 +5792,7 @@ bool DxfDialog::Create(MyFrame * parent, wxString & dir_path,
   Force3D = false;
   LinkedRings = false;
   UnlinkedRings = false;
-  ImportMixed = false;
+  ImportMixed = true;
   AppendMode = true;
   if (wxDialog::Create(parent, wxID_ANY, wxT("Import DXF Drawings")) == false)
     return false;
@@ -5581,7 +5851,7 @@ void DxfDialog::CreateControls()
   sridSizer->Add(sridCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
   wxCheckBox *AppendCtrl = new wxCheckBox(this, ID_DXF_APPEND,
                                           wxT
-                                          ("Append to already exixing tables"),
+                                          ("Append to already existing tables"),
                                           wxDefaultPosition, wxDefaultSize);
   sridSizer->Add(AppendCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
   AppendCtrl->SetValue(true);
@@ -5635,8 +5905,8 @@ void DxfDialog::CreateControls()
   boxSizer->Add(dxfDimsSel, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
 // sixth row: import mode
   wxString dxfMode[3];
-  dxfMode[0] = wxT("preserve &distinct DXF layers");
-  dxfMode[1] = wxT("&mixed layers (distinct by type)");
+  dxfMode[0] = wxT("&mixed layers (distinct by type)");
+  dxfMode[1] = wxT("preserve &distinct DXF layers");
   wxRadioBox *dxfModeSel = new wxRadioBox(this, ID_DXF_MIXED,
                                           wxT("&Import mode"),
                                           wxDefaultPosition,
@@ -5750,9 +6020,9 @@ void DxfDialog::OnModeChanged(wxCommandEvent & WXUNUSED(event))
 // Import mode radio box
 //
   wxRadioBox *modeSel = (wxRadioBox *) FindWindow(ID_DXF_MIXED);
-  ImportMixed = false;
+  ImportMixed = true;
   if (modeSel->GetSelection() == 1)
-    ImportMixed = true;
+    ImportMixed = false;
 }
 
 void DxfDialog::OnPrefixChanged(wxCommandEvent & WXUNUSED(event))
diff --git a/DialogsGraph.cpp b/DialogsGraph.cpp
index 9b5b58d..da6cc37 100644
--- a/DialogsGraph.cpp
+++ b/DialogsGraph.cpp
@@ -31,7 +31,8 @@
 #include "wx/colordlg.h"
 #include "wx/clipbrd.h"
 
-#include <gaiagraphics.h>
+#include <rasterlite2/rasterlite2.h>
+#include <rasterlite2/rl2graphics.h>
 
 #if defined(_WIN32) || defined (__MINGW32__)
 #define FORMAT_64	"%I64d"
@@ -1099,9 +1100,9 @@ void StatsChartDialog::DoIntervalHistogram(int hsize, int vsize, int target,
 {
 // generating an Histogram (Interval values)
   unsigned char *rgb_array = NULL;
-  const void *gr = NULL;
-  const void *font = NULL;
-  const void *font_big = NULL;
+  rl2GraphicsContextPtr ctx = NULL;
+  rl2GraphicsFontPtr font = NULL;
+  rl2GraphicsFontPtr font_big = NULL;
   int idx;
   int start_x;
   int end_x;
@@ -1149,27 +1150,44 @@ void StatsChartDialog::DoIntervalHistogram(int hsize, int vsize, int target,
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
+      ctx = rl2_graph_create_svg_context(xpath, hsize, vsize);
   } else if (target == CHART_TARGET_IS_PDF)
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
-                             &gr);
+      // assuming A4 300 DPI
+      double pageWidth = 8.3;
+      double pageHeight = 11.7;
+      if (hsize > vsize)
+        {
+          // landscape
+          pageWidth = 11.7;
+          pageHeight = 8.3;
+        }
+      double pdf_hsize = (pageWidth - 2.0) * 300.0;
+      double pdf_vsize = (pageHeight - 2.0) * 300.0;
+      hsize = (int) pdf_hsize;
+      vsize = (int) pdf_vsize;
+      ctx =
+        rl2_graph_create_pdf_context(xpath, 300, pageWidth, pageHeight, 1, 1);
   } else
-    gGraphCreateContext(hsize, vsize, &gr);
+    ctx = rl2_graph_create_context(hsize, vsize);
+  if (ctx == NULL)
+    goto done;
 
 // background initialization
-  gGraphSetBrush(gr, 255, 255, 255, 255);
-  gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
+  rl2_graph_set_brush(ctx, 255, 255, 255, 255);
+  rl2_graph_draw_rectangle(ctx, -1, -1, hsize + 2, vsize + 2);
 
 // font setup
-  gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_NORMAL,
-                   &font);
-  gGraphFontSetColor(font, 0, 0, 0, 255);
-  gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_BOLD,
-                   &font_big);
-  gGraphFontSetColor(font_big, 0, 0, 0, 255);
+  font =
+    rl2_graph_create_toy_font(NULL, font_size, RL2_FONTSTYLE_NORMAL,
+                              RL2_FONTWEIGHT_NORMAL);
+  rl2_graph_font_set_color(font, 0, 0, 0, 255);
+  font_big =
+    rl2_graph_create_toy_font(NULL, font_size, RL2_FONTSTYLE_NORMAL,
+                              RL2_FONTWEIGHT_BOLD);
+  rl2_graph_font_set_color(font_big, 0, 0, 0, 255);
 
 // computing TEXT sizes
   strcpy(table, Table.ToUTF8());
@@ -1177,40 +1195,40 @@ void StatsChartDialog::DoIntervalHistogram(int hsize, int vsize, int target,
   MainFrame->DoubleQuotedSql(table);
   MainFrame->DoubleQuotedSql(column);
   sprintf(title, "Dataset: %s.%s     [interval values]", table, column);
-  gGraphSetFont(gr, font_big);
-  gGraphGetTextExtent(gr, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
-                      &post_x, &post_y);
+  rl2_graph_set_font(ctx, font_big);
+  rl2_graph_get_text_extent(ctx, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
+                            &post_x, &post_y);
   title_x = (hsize - (int) txtWidth) / 2;
   title_y = 5 + (int) titleHeight;
 // measuring class labels
-  gGraphSetFont(gr, font);
+  rl2_graph_set_font(ctx, font);
   sprintf(text, "%1.4f", Min);
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
   labelWidth = txtWidth;
   sprintf(text, "%1.4f", Min + ((Max - Min) / 4.0));
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
   if (txtWidth > labelWidth)
     labelWidth = txtWidth;
   sprintf(text, "%1.4f", Min + ((Max - Min) / 2.0));
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
   if (txtWidth > labelWidth)
     labelWidth = txtWidth;
   sprintf(text, "%1.4f", Min + (((Max - Min) / 4.0) * 3.0));
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
   if (txtWidth > labelWidth)
     labelWidth = txtWidth;
   sprintf(text, "%1.4f", Max);
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
   if (txtWidth > labelWidth)
     labelWidth = txtWidth;
 
@@ -1224,10 +1242,10 @@ void StatsChartDialog::DoIntervalHistogram(int hsize, int vsize, int target,
   pLab = scaleLabels.GetFirst();
   while (pLab)
     {
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, pLab->GetLabel().ToUTF8());
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
       if (txtWidth > scaleWidth)
         scaleWidth = txtWidth;
       pLab = pLab->GetNext();
@@ -1241,119 +1259,133 @@ void StatsChartDialog::DoIntervalHistogram(int hsize, int vsize, int target,
   labelStep = (end_x - start_x - step_x) / 4;
 
 // title output
-  gGraphSetFont(gr, font_big);
-  gGraphDrawText(gr, title, title_x, title_y, 0.0);
+  rl2_graph_set_font(ctx, font_big);
+  rl2_graph_draw_text(ctx, title, title_x, title_y, 0.0, 0.0, 0.0);
 // class labels output
-  gGraphSetFont(gr, font);
+  rl2_graph_set_font(ctx, font);
   sprintf(text, "%1.4f", Min);
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, labelBase + txtHeight,
-                 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, labelBase + txtHeight,
+                      vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
   labelBase += labelStep;
   sprintf(text, "%1.4f", Min + ((Max - Min) / 4.0));
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, labelBase + txtHeight,
-                 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, labelBase + txtHeight,
+                      vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
   labelBase += labelStep;
   sprintf(text, "%1.4f", Min + ((Max - Min) / 2.0));
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, labelBase + txtHeight,
-                 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, labelBase + txtHeight,
+                      vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
   labelBase += labelStep;
   sprintf(text, "%1.4f", Min + (((Max - Min) / 4.0) * 3.0));
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, labelBase + txtHeight,
-                 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, labelBase + txtHeight,
+                      vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
   labelBase += labelStep;
   sprintf(text, "%1.4f", Max);
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, labelBase + txtHeight,
-                 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, labelBase + txtHeight,
+                      vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
 
   for (idx = 0; idx < ChartData.GetNumClasses(); idx++)
     {
       // drawing bars
       MyChartIntervalClass *p = ChartData.GetClass(idx);
-      gGraphSetPen(gr, 0, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
+      rl2_graph_set_solid_pen(ctx, 0, 0, 0, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
       color_idx = idx % 8;
-      gGraphSetBrush(gr, colors[color_idx].Red(), colors[color_idx].Green(),
-                     colors[color_idx].Blue(), 255);
+      rl2_graph_set_brush(ctx, colors[color_idx].Red(),
+                          colors[color_idx].Green(), colors[color_idx].Blue(),
+                          255);
       height =
         vspan * ((double) (p->GetCount() / (double) (ChartData.GetMaxFreq())));
-      gGraphDrawRectangle(gr, base_x, base_y - height, step_x, height);
+      rl2_graph_draw_rectangle(ctx, base_x, base_y - height, step_x, height);
       base_x += step_x;
     }
 // drawing 'scale' labels
   pLab = scaleLabels.GetFirst();
   while (pLab)
     {
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, pLab->GetLabel().ToUTF8());
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
-      gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
-                     base_y - pLab->GetPosition() + (txtHeight / 2.0), 0.0);
-      gGraphSetPen(gr, 255, 128, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
-      gGraphStrokeLine(gr, start_x, base_y - pLab->GetPosition(), end_x,
-                       base_y - pLab->GetPosition());
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
+      rl2_graph_draw_text(ctx, text, scaleWidth - txtWidth + 5,
+                          base_y - pLab->GetPosition() + (txtHeight / 2.0),
+                          0.0, 0.0, 0.0);
+      rl2_graph_set_solid_pen(ctx, 255, 128, 128, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
+      rl2_graph_stroke_line(ctx, start_x, base_y - pLab->GetPosition(), end_x,
+                            base_y - pLab->GetPosition());
       pLab = pLab->GetNext();
     }
 // marking the ZERO baseline
-  gGraphSetFont(gr, font);
+  rl2_graph_set_font(ctx, font);
   strcpy(text, "0");
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
-                 base_y + (txtHeight / 2.0), 0.0);
-  gGraphSetPen(gr, 255, 128, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
-  gGraphStrokeLine(gr, start_x, base_y, end_x, base_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, scaleWidth - txtWidth + 5,
+                      base_y + (txtHeight / 2.0), 0.0, 0.0, 0.0);
+  rl2_graph_set_solid_pen(ctx, 255, 128, 128, 255, 1, RL2_PEN_CAP_ROUND,
+                          RL2_PEN_JOIN_ROUND);
+  rl2_graph_stroke_line(ctx, start_x, base_y, end_x, base_y);
 
 // graphics finalization
-  gGraphDestroyFont(font);
-  gGraphDestroyFont(font_big);
+  rl2_graph_destroy_font(font);
+  rl2_graph_destroy_font(font_big);
   if (target == CHART_TARGET_IS_COPY || target == CHART_TARGET_IS_PNG
       || target == CHART_TARGET_IS_PREVIEW)
-    gGraphGetContextRgbArray(gr, &rgb_array);
-  if (target == CHART_TARGET_IS_SVG)
-    gGraphDestroySvgContext(gr);
-  else if (target == CHART_TARGET_IS_PDF)
-    gGraphDestroyPdfContext(gr);
-  else
-    gGraphDestroyContext(gr);
+    rgb_array = rl2_graph_get_context_rgb_array(ctx);
+  if (ctx != NULL)
+    rl2_graph_destroy_context(ctx);
 
+done:
   if (target == CHART_TARGET_IS_PNG)
     {
       if (rgb_array)
         {
           // creating the Image from RGB array
-          const void *img =
-            gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
-          if (img)
+          int err = 1;
+          unsigned char *png;
+          int png_size;
+          if (rl2_rgb_to_png(hsize, vsize, rgb_array, &png, &png_size) ==
+              RL2_OK)
             {
               char xpath[2024];
               strcpy(xpath, ExportPath.ToUTF8());
-              if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
+              FILE *out = fopen(xpath, "wb");
+              if (out == NULL)
+                err = 1;
+              else
                 {
-                  wxString msg =
-                    wxT
-                    ("An error occurred while saving\nthe current Char as PNG");
-                  wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
-                               MainFrame);
+                  int wr = fwrite(png, 1, png_size, out);
+                  if (wr == png_size)
+                    err = 0;
+                  fclose(out);
                 }
-              gGraphDestroyImage(img);
+              free(rgb_array);
+            }
+          if (err)
+            {
+              wxString msg =
+                wxT("An error occurred while saving\nthe current Chart as PNG");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
+                           MainFrame);
             }
         }
     }
+
   if (target == CHART_TARGET_IS_PREVIEW)
     {
       if (rgb_array)
@@ -1386,9 +1418,9 @@ void StatsChartDialog::DoIntervalLineChart(int hsize, int vsize, int target,
 {
 // generating a Line Chart (Interval values)
   unsigned char *rgb_array = NULL;
-  const void *gr = NULL;
-  const void *font = NULL;
-  const void *font_big = NULL;
+  rl2GraphicsContextPtr ctx = NULL;
+  rl2GraphicsFontPtr font = NULL;
+  rl2GraphicsFontPtr font_big = NULL;
   int idx;
   int start_x;
   int end_x;
@@ -1424,27 +1456,44 @@ void StatsChartDialog::DoIntervalLineChart(int hsize, int vsize, int target,
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
+      ctx = rl2_graph_create_svg_context(xpath, hsize, vsize);
   } else if (target == CHART_TARGET_IS_PDF)
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
-                             &gr);
+      // assuming A4 300 DPI
+      double pageWidth = 8.3;
+      double pageHeight = 11.7;
+      if (hsize > vsize)
+        {
+          // landscape
+          pageWidth = 11.7;
+          pageHeight = 8.3;
+        }
+      double pdf_hsize = (pageWidth - 2.0) * 300.0;
+      double pdf_vsize = (pageHeight - 2.0) * 300.0;
+      hsize = (int) pdf_hsize;
+      vsize = (int) pdf_vsize;
+      ctx =
+        rl2_graph_create_pdf_context(xpath, 300, pageWidth, pageHeight, 1, 1);
   } else
-    gGraphCreateContext(hsize, vsize, &gr);
+    ctx = rl2_graph_create_context(hsize, vsize);
+  if (ctx == NULL)
+    goto done;
 
 // background initialization
-  gGraphSetBrush(gr, 255, 255, 255, 255);
-  gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
+  rl2_graph_set_brush(ctx, 255, 255, 255, 255);
+  rl2_graph_draw_rectangle(ctx, -1, -1, hsize + 2, vsize + 2);
 
 // font setup
-  gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_NORMAL,
-                   &font);
-  gGraphFontSetColor(font, 0, 0, 0, 255);
-  gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_BOLD,
-                   &font_big);
-  gGraphFontSetColor(font_big, 0, 0, 0, 255);
+  font =
+    rl2_graph_create_toy_font(NULL, font_size, RL2_FONTSTYLE_NORMAL,
+                              RL2_FONTWEIGHT_NORMAL);
+  rl2_graph_font_set_color(font, 0, 0, 0, 255);
+  font_big =
+    rl2_graph_create_toy_font(NULL, font_size, RL2_FONTSTYLE_NORMAL,
+                              RL2_FONTWEIGHT_BOLD);
+  rl2_graph_font_set_color(font_big, 0, 0, 0, 255);
 
 // computing TEXT sizes
   strcpy(table, Table.ToUTF8());
@@ -1452,40 +1501,40 @@ void StatsChartDialog::DoIntervalLineChart(int hsize, int vsize, int target,
   MainFrame->DoubleQuotedSql(table);
   MainFrame->DoubleQuotedSql(column);
   sprintf(title, "Dataset: %s.%s     [interval values]", table, column);
-  gGraphSetFont(gr, font_big);
-  gGraphGetTextExtent(gr, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
-                      &post_x, &post_y);
+  rl2_graph_set_font(ctx, font_big);
+  rl2_graph_get_text_extent(ctx, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
+                            &post_x, &post_y);
   title_x = (hsize - (int) txtWidth) / 2;
   title_y = 5 + (int) titleHeight;
 // measuring class labels
-  gGraphSetFont(gr, font);
+  rl2_graph_set_font(ctx, font);
   sprintf(text, "%1.4f", Min);
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
   labelWidth = txtWidth;
   sprintf(text, "%1.4f", Min + ((Max - Min) / 4.0));
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
   if (txtWidth > labelWidth)
     labelWidth = txtWidth;
   sprintf(text, "%1.4f", Min + ((Max - Min) / 2.0));
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
   if (txtWidth > labelWidth)
     labelWidth = txtWidth;
   sprintf(text, "%1.4f", Min + (((Max - Min) / 4.0) * 3.0));
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
   if (txtWidth > labelWidth)
     labelWidth = txtWidth;
   sprintf(text, "%1.4f", Max);
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
   if (txtWidth > labelWidth)
     labelWidth = txtWidth;
 
@@ -1499,10 +1548,10 @@ void StatsChartDialog::DoIntervalLineChart(int hsize, int vsize, int target,
   pLab = scaleLabels.GetFirst();
   while (pLab)
     {
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, pLab->GetLabel().ToUTF8());
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
       if (txtWidth > scaleWidth)
         scaleWidth = txtWidth;
       pLab = pLab->GetNext();
@@ -1516,53 +1565,54 @@ void StatsChartDialog::DoIntervalLineChart(int hsize, int vsize, int target,
   labelStep = (end_x - start_x - step_x) / 4;
 
 // title output
-  gGraphSetFont(gr, font_big);
-  gGraphDrawText(gr, title, title_x, title_y, 0.0);
+  rl2_graph_set_font(ctx, font_big);
+  rl2_graph_draw_text(ctx, title, title_x, title_y, 0.0, 0.0, 0.0);
 // class labels output
-  gGraphSetFont(gr, font);
+  rl2_graph_set_font(ctx, font);
   sprintf(text, "%1.4f", Min);
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, labelBase + txtHeight,
-                 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, labelBase + txtHeight,
+                      vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
   labelBase += labelStep;
   sprintf(text, "%1.4f", Min + ((Max - Min) / 4.0));
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, labelBase + txtHeight,
-                 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, labelBase + txtHeight,
+                      vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
   labelBase += labelStep;
   sprintf(text, "%1.4f", Min + ((Max - Min) / 2.0));
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, labelBase + txtHeight,
-                 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, labelBase + txtHeight,
+                      vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
   labelBase += labelStep;
   sprintf(text, "%1.4f", Min + (((Max - Min) / 4.0) * 3.0));
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, labelBase + txtHeight,
-                 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, labelBase + txtHeight,
+                      vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
   labelBase += labelStep;
   sprintf(text, "%1.4f", Max);
   CleanDecimals(text);
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, labelBase + txtHeight,
-                 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, labelBase + txtHeight,
+                      vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
 
   for (idx = 0; idx < ChartData.GetNumClasses(); idx++)
     {
       MyChartIntervalClass *p = ChartData.GetClass(idx);
       height =
         vspan * ((double) (p->GetCount() / (double) (ChartData.GetMaxFreq())));
-      gGraphSetPen(gr, 192, 192, 192, 255, 1, GGRAPH_PENSTYLE_DOT);
-      gGraphStrokeLine(gr, base_x + (step_x / 2.0), start_y,
-                       base_x + (step_x / 2.0), base_y - height);
+      rl2_graph_set_solid_pen(ctx, 192, 192, 192, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
+      rl2_graph_stroke_line(ctx, base_x + (step_x / 2.0), start_y,
+                            base_x + (step_x / 2.0), base_y - height);
       base_x += step_x;
     }
   base_x = start_x;
@@ -1572,75 +1622,89 @@ void StatsChartDialog::DoIntervalLineChart(int hsize, int vsize, int target,
       height =
         vspan * ((double) (p->GetCount() / (double) (ChartData.GetMaxFreq())));
       if (idx == 0)
-        gGraphMoveToPoint(gr, base_x + (step_x / 2.0), base_y - height);
+        rl2_graph_move_to_point(ctx, base_x + (step_x / 2.0), base_y - height);
       else
-        gGraphAddLineToPath(gr, base_x + (step_x / 2.0), base_y - height);
+        rl2_graph_add_line_to_path(ctx, base_x + (step_x / 2.0),
+                                   base_y - height);
       base_x += step_x;
     }
-  gGraphSetPen(gr, 255, 0, 0, 255, 2, GGRAPH_PENSTYLE_SOLID);
-  gGraphStrokePath(gr, GGRAPH_CLEAR_PATH);
+  rl2_graph_set_solid_pen(ctx, 255, 0, 0, 255, 2, RL2_PEN_CAP_ROUND,
+                          RL2_PEN_JOIN_ROUND);
+  rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
 
 // drawing 'scale' labels
   pLab = scaleLabels.GetFirst();
   while (pLab)
     {
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, pLab->GetLabel().ToUTF8());
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
-      gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
-                     base_y - pLab->GetPosition() + (txtHeight / 2.0), 0.0);
-      gGraphSetPen(gr, 128, 255, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
-      gGraphStrokeLine(gr, start_x, base_y - pLab->GetPosition(), end_x,
-                       base_y - pLab->GetPosition());
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
+      rl2_graph_draw_text(ctx, text, scaleWidth - txtWidth + 5,
+                          base_y - pLab->GetPosition() + (txtHeight / 2.0), 0.0,
+                          0.0, 0.0);
+      rl2_graph_set_solid_pen(ctx, 128, 255, 128, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
+      rl2_graph_stroke_line(ctx, start_x, base_y - pLab->GetPosition(), end_x,
+                            base_y - pLab->GetPosition());
       pLab = pLab->GetNext();
     }
 // marking the ZERO baseline
-  gGraphSetFont(gr, font);
+  rl2_graph_set_font(ctx, font);
   strcpy(text, "0");
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
-                 base_y + (txtHeight / 2.0), 0.0);
-  gGraphSetPen(gr, 128, 255, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
-  gGraphStrokeLine(gr, start_x, base_y, end_x, base_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, scaleWidth - txtWidth + 5,
+                      base_y + (txtHeight / 2.0), 0.0, 0.0, 0.0);
+  rl2_graph_set_solid_pen(ctx, 128, 255, 128, 255, 1, RL2_PEN_CAP_ROUND,
+                          RL2_PEN_JOIN_ROUND);
+  rl2_graph_stroke_line(ctx, start_x, base_y, end_x, base_y);
 
 // graphics finalization
-  gGraphDestroyFont(font);
-  gGraphDestroyFont(font_big);
+  rl2_graph_destroy_font(font);
+  rl2_graph_destroy_font(font_big);
   if (target == CHART_TARGET_IS_COPY || target == CHART_TARGET_IS_PNG
       || target == CHART_TARGET_IS_PREVIEW)
-    gGraphGetContextRgbArray(gr, &rgb_array);
-  if (target == CHART_TARGET_IS_SVG)
-    gGraphDestroySvgContext(gr);
-  else if (target == CHART_TARGET_IS_PDF)
-    gGraphDestroyPdfContext(gr);
-  else
-    gGraphDestroyContext(gr);
+    rgb_array = rl2_graph_get_context_rgb_array(ctx);
+  if (ctx != NULL)
+    rl2_graph_destroy_context(ctx);
 
+done:
   if (target == CHART_TARGET_IS_PNG)
     {
       if (rgb_array)
         {
           // creating the Image from RGB array
-          const void *img =
-            gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
-          if (img)
+          int err = 1;
+          unsigned char *png;
+          int png_size;
+          if (rl2_rgb_to_png(hsize, vsize, rgb_array, &png, &png_size) ==
+              RL2_OK)
             {
               char xpath[2024];
               strcpy(xpath, ExportPath.ToUTF8());
-              if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
+              FILE *out = fopen(xpath, "wb");
+              if (out == NULL)
+                err = 1;
+              else
                 {
-                  wxString msg =
-                    wxT
-                    ("An error occurred while saving\nthe current Char as PNG");
-                  wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
-                               MainFrame);
+                  int wr = fwrite(png, 1, png_size, out);
+                  if (wr == png_size)
+                    err = 0;
+                  fclose(out);
                 }
-              gGraphDestroyImage(img);
+              free(rgb_array);
+            }
+          if (err)
+            {
+              wxString msg =
+                wxT("An error occurred while saving\nthe current Chart as PNG");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
+                           MainFrame);
             }
         }
     }
+
   if (target == CHART_TARGET_IS_PREVIEW)
     {
       if (rgb_array)
@@ -1673,9 +1737,9 @@ void StatsChartDialog::DoIntervalPieChart(int hsize, int vsize, int target,
 {
 // generating a Pie Chart (Interval values)
   unsigned char *rgb_array = NULL;
-  const void *gr = NULL;
-  const void *font = NULL;
-  const void *font_big = NULL;
+  rl2GraphicsContextPtr ctx = NULL;
+  rl2GraphicsFontPtr font = NULL;
+  rl2GraphicsFontPtr font_big = NULL;
   int idx;
   double radius_x;
   double radius_y;
@@ -1722,27 +1786,44 @@ void StatsChartDialog::DoIntervalPieChart(int hsize, int vsize, int target,
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
+      ctx = rl2_graph_create_svg_context(xpath, hsize, vsize);
   } else if (target == CHART_TARGET_IS_PDF)
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
-                             &gr);
+      // assuming A4 300 DPI
+      double pageWidth = 8.3;
+      double pageHeight = 11.7;
+      if (hsize > vsize)
+        {
+          // landscape
+          pageWidth = 11.7;
+          pageHeight = 8.3;
+        }
+      double pdf_hsize = (pageWidth - 2.0) * 300.0;
+      double pdf_vsize = (pageHeight - 2.0) * 300.0;
+      hsize = (int) pdf_hsize;
+      vsize = (int) pdf_vsize;
+      ctx =
+        rl2_graph_create_pdf_context(xpath, 300, pageWidth, pageHeight, 1, 1);
   } else
-    gGraphCreateContext(hsize, vsize, &gr);
+    ctx = rl2_graph_create_context(hsize, vsize);
+  if (ctx == NULL)
+    goto done;
 
 // background initialization
-  gGraphSetBrush(gr, 255, 255, 255, 255);
-  gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
+  rl2_graph_set_brush(ctx, 255, 255, 255, 255);
+  rl2_graph_draw_rectangle(ctx, -1, -1, hsize + 2, vsize + 2);
 
 // font setup
-  gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_NORMAL,
-                   &font);
-  gGraphFontSetColor(font, 0, 0, 0, 255);
-  gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_BOLD,
-                   &font_big);
-  gGraphFontSetColor(font_big, 0, 0, 0, 255);
+  font =
+    rl2_graph_create_toy_font(NULL, font_size, RL2_FONTSTYLE_NORMAL,
+                              RL2_FONTWEIGHT_NORMAL);
+  rl2_graph_font_set_color(font, 0, 0, 0, 255);
+  font_big =
+    rl2_graph_create_toy_font(NULL, font_size, RL2_FONTSTYLE_NORMAL,
+                              RL2_FONTWEIGHT_BOLD);
+  rl2_graph_font_set_color(font_big, 0, 0, 0, 255);
 
 // computing TEXT sizes
   strcpy(table, Table.ToUTF8());
@@ -1750,20 +1831,20 @@ void StatsChartDialog::DoIntervalPieChart(int hsize, int vsize, int target,
   MainFrame->DoubleQuotedSql(table);
   MainFrame->DoubleQuotedSql(column);
   sprintf(title, "Dataset: %s.%s     [interval values]", table, column);
-  gGraphSetFont(gr, font_big);
-  gGraphGetTextExtent(gr, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
-                      &post_x, &post_y);
+  rl2_graph_set_font(ctx, font_big);
+  rl2_graph_get_text_extent(ctx, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
+                            &post_x, &post_y);
   title_x = (hsize - (int) txtWidth) / 2;
   title_y = 5 + (int) titleHeight;
   for (idx = 0; idx < ChartData.GetNumClasses(); idx++)
     {
       // measuring labels
       MyChartIntervalClass *p = ChartData.GetClass(idx);
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       sprintf(text, "%1.4f", p->GetMin() + ((p->GetMax() - p->GetMin()) / 2.0));
       CleanDecimals(text);
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
       if (txtWidth > labelWidth)
         labelWidth = txtWidth;
     }
@@ -1780,21 +1861,23 @@ void StatsChartDialog::DoIntervalPieChart(int hsize, int vsize, int target,
     radius = radius_y;
 
 // title output
-  gGraphSetFont(gr, font_big);
-  gGraphDrawText(gr, title, title_x, title_y, 0.0);
+  rl2_graph_set_font(ctx, font_big);
+  rl2_graph_draw_text(ctx, title, title_x, title_y, 0.0, 0.0, 0.0);
 
   from = 0.0;
   for (idx = 0; idx < ChartData.GetNumClasses(); idx++)
     {
       MyChartIntervalClass *p = ChartData.GetClass(idx);
-      gGraphSetPen(gr, 0, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
+      rl2_graph_set_solid_pen(ctx, 0, 0, 0, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
       color_idx = idx % 8;
-      gGraphSetBrush(gr, colors[color_idx].Red(), colors[color_idx].Green(),
-                     colors[color_idx].Blue(), 255);
+      rl2_graph_set_brush(ctx, colors[color_idx].Red(),
+                          colors[color_idx].Green(), colors[color_idx].Blue(),
+                          255);
       step =
         (M_PI * 2.0) *
         ((double) (p->GetCount() / (double) (ChartData.GetTotFreq())));
-      gGraphDrawCircleSector(gr, cx, cy, radius, from, from + step);
+      rl2_graph_draw_circle_sector(ctx, cx, cy, radius, from, from + step);
       sprintf(text, "%1.4f", p->GetMin() + ((p->GetMax() - p->GetMin()) / 2.0));
       CleanDecimals(text);
       lx = cx + (radius * 0.90) * cos(from + (step / 2.0));
@@ -1811,12 +1894,15 @@ void StatsChartDialog::DoIntervalPieChart(int hsize, int vsize, int target,
       // printing Left labels
       pLab = labels.GetLeftLabel(idx);
       strcpy(text, pLab->GetLabel().ToUTF8());
-      gGraphSetFont(gr, font);
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
-      gGraphDrawText(gr, text, 10, base_y + (txtHeight / 2.0), 0.0);
-      gGraphSetPen(gr, 255, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
-      gGraphStrokeLine(gr, 10 + txtWidth, base_y, pLab->GetX(), pLab->GetY());
+      rl2_graph_set_font(ctx, font);
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
+      rl2_graph_draw_text(ctx, text, 10, base_y + (txtHeight / 2.0), 0.0, 0.0,
+                          0.0);
+      rl2_graph_set_solid_pen(ctx, 255, 0, 0, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
+      rl2_graph_stroke_line(ctx, 10 + txtWidth, base_y, pLab->GetX(),
+                            pLab->GetY());
       base_y += step_y;
     }
   step_y = (double) (vsize - 50) / (double) (labels.GetNumRightLabels() - 1);
@@ -1826,53 +1912,63 @@ void StatsChartDialog::DoIntervalPieChart(int hsize, int vsize, int target,
       // printing Right labels
       pLab = labels.GetRightLabel(idx);
       strcpy(text, pLab->GetLabel().ToUTF8());
-      gGraphSetFont(gr, font);
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
-      gGraphDrawText(gr, text, hsize - txtWidth - 10,
-                     base_y + (txtHeight / 2.0), 0.0);
-      gGraphSetPen(gr, 255, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
-      gGraphStrokeLine(gr, hsize - txtWidth - 10, base_y, pLab->GetX(),
-                       pLab->GetY());
+      rl2_graph_set_font(ctx, font);
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
+      rl2_graph_draw_text(ctx, text, hsize - txtWidth - 10,
+                          base_y + (txtHeight / 2.0), 0.0, 0.0, 0.0);
+      rl2_graph_set_solid_pen(ctx, 255, 0, 0, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
+      rl2_graph_stroke_line(ctx, hsize - txtWidth - 10, base_y, pLab->GetX(),
+                            pLab->GetY());
       base_y += step_y;
     }
 
 // graphics finalization
-  gGraphDestroyFont(font);
-  gGraphDestroyFont(font_big);
+  rl2_graph_destroy_font(font);
+  rl2_graph_destroy_font(font_big);
   if (target == CHART_TARGET_IS_COPY || target == CHART_TARGET_IS_PNG
       || target == CHART_TARGET_IS_PREVIEW)
-    gGraphGetContextRgbArray(gr, &rgb_array);
-  if (target == CHART_TARGET_IS_SVG)
-    gGraphDestroySvgContext(gr);
-  else if (target == CHART_TARGET_IS_PDF)
-    gGraphDestroyPdfContext(gr);
-  else
-    gGraphDestroyContext(gr);
+    rgb_array = rl2_graph_get_context_rgb_array(ctx);
+  if (ctx != NULL)
+    rl2_graph_destroy_context(ctx);
 
+done:
   if (target == CHART_TARGET_IS_PNG)
     {
       if (rgb_array)
         {
           // creating the Image from RGB array
-          const void *img =
-            gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
-          if (img)
+          int err = 1;
+          unsigned char *png;
+          int png_size;
+          if (rl2_rgb_to_png(hsize, vsize, rgb_array, &png, &png_size) ==
+              RL2_OK)
             {
               char xpath[2024];
               strcpy(xpath, ExportPath.ToUTF8());
-              if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
+              FILE *out = fopen(xpath, "wb");
+              if (out == NULL)
+                err = 1;
+              else
                 {
-                  wxString msg =
-                    wxT
-                    ("An error occurred while saving\nthe current Char as PNG");
-                  wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
-                               MainFrame);
+                  int wr = fwrite(png, 1, png_size, out);
+                  if (wr == png_size)
+                    err = 0;
+                  fclose(out);
                 }
-              gGraphDestroyImage(img);
+              free(rgb_array);
+            }
+          if (err)
+            {
+              wxString msg =
+                wxT("An error occurred while saving\nthe current Chart as PNG");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
+                           MainFrame);
             }
         }
     }
+
   if (target == CHART_TARGET_IS_PREVIEW)
     {
       if (rgb_array)
@@ -1905,9 +2001,9 @@ void StatsChartDialog::DoUniqueHistogram(int hsize, int vsize, int target,
 {
 // generating an Histogram (Unique values)
   unsigned char *rgb_array = NULL;
-  const void *gr = NULL;
-  const void *font = NULL;
-  const void *font_big = NULL;
+  rl2GraphicsContextPtr ctx = NULL;
+  rl2GraphicsFontPtr font = NULL;
+  rl2GraphicsFontPtr font_big = NULL;
   int idx;
   MyChartUniqueClass *p;
   int start_x;
@@ -1955,27 +2051,44 @@ void StatsChartDialog::DoUniqueHistogram(int hsize, int vsize, int target,
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
+      ctx = rl2_graph_create_svg_context(xpath, hsize, vsize);
   } else if (target == CHART_TARGET_IS_PDF)
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
-                             &gr);
+      // assuming A4 300 DPI
+      double pageWidth = 8.3;
+      double pageHeight = 11.7;
+      if (hsize > vsize)
+        {
+          // landscape
+          pageWidth = 11.7;
+          pageHeight = 8.3;
+        }
+      double pdf_hsize = (pageWidth - 2.0) * 300.0;
+      double pdf_vsize = (pageHeight - 2.0) * 300.0;
+      hsize = (int) pdf_hsize;
+      vsize = (int) pdf_vsize;
+      ctx =
+        rl2_graph_create_pdf_context(xpath, 300, pageWidth, pageHeight, 1, 1);
   } else
-    gGraphCreateContext(hsize, vsize, &gr);
+    ctx = rl2_graph_create_context(hsize, vsize);
+  if (ctx == NULL)
+    goto done;
 
 // background initialization
-  gGraphSetBrush(gr, 255, 255, 255, 255);
-  gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
+  rl2_graph_set_brush(ctx, 255, 255, 255, 255);
+  rl2_graph_draw_rectangle(ctx, -1, -1, hsize + 2, vsize + 2);
 
 // font setup
-  gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_NORMAL,
-                   &font);
-  gGraphFontSetColor(font, 0, 0, 0, 255);
-  gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_BOLD,
-                   &font_big);
-  gGraphFontSetColor(font_big, 0, 0, 0, 255);
+  font =
+    rl2_graph_create_toy_font(NULL, font_size, RL2_FONTSTYLE_NORMAL,
+                              RL2_FONTWEIGHT_NORMAL);
+  rl2_graph_font_set_color(font, 0, 0, 0, 255);
+  font_big =
+    rl2_graph_create_toy_font(NULL, font_size, RL2_FONTSTYLE_NORMAL,
+                              RL2_FONTWEIGHT_BOLD);
+  rl2_graph_font_set_color(font_big, 0, 0, 0, 255);
 
   if (ChartData.GetOtherUniquesFreq() > 0)
     others = 1;
@@ -1985,16 +2098,16 @@ void StatsChartDialog::DoUniqueHistogram(int hsize, int vsize, int target,
   MainFrame->DoubleQuotedSql(table);
   MainFrame->DoubleQuotedSql(column);
   sprintf(title, "Dataset: %s.%s     [unique values]", table, column);
-  gGraphSetFont(gr, font_big);
-  gGraphGetTextExtent(gr, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
-                      &post_x, &post_y);
+  rl2_graph_set_font(ctx, font_big);
+  rl2_graph_get_text_extent(ctx, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
+                            &post_x, &post_y);
   title_x = (hsize - (int) txtWidth) / 2;
   title_y = 5 + (int) titleHeight;
 // measuring class labels
   p = ChartData.GetFirst();
   while (p)
     {
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, p->GetValue().ToUTF8());
       if (strlen(text) > 10)
         {
@@ -2002,8 +2115,8 @@ void StatsChartDialog::DoUniqueHistogram(int hsize, int vsize, int target,
           text[11] = '.';
           text[12] = '\0';      // truncating to max 10 chars
         }
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
       if (txtWidth > labelWidth)
         labelWidth = txtWidth;
       p = p->GetNext();
@@ -2011,9 +2124,9 @@ void StatsChartDialog::DoUniqueHistogram(int hsize, int vsize, int target,
   if (others)
     {
       // including the 'any other' class
-      gGraphSetFont(gr, font);
-      gGraphGetTextExtent(gr, "AnyOther", &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
+      rl2_graph_set_font(ctx, font);
+      rl2_graph_get_text_extent(ctx, "AnyOther", &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
       if (txtWidth > labelWidth)
         labelWidth = txtWidth;
     }
@@ -2028,10 +2141,10 @@ void StatsChartDialog::DoUniqueHistogram(int hsize, int vsize, int target,
   pLab = scaleLabels.GetFirst();
   while (pLab)
     {
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, pLab->GetLabel().ToUTF8());
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
       if (txtWidth > scaleWidth)
         scaleWidth = txtWidth;
       pLab = pLab->GetNext();
@@ -2044,13 +2157,13 @@ void StatsChartDialog::DoUniqueHistogram(int hsize, int vsize, int target,
     (double) (end_x - start_x) / (double) (ChartData.GetNumClasses() + others);
 
 // title output
-  gGraphSetFont(gr, font_big);
-  gGraphDrawText(gr, title, title_x, title_y, 0.0);
+  rl2_graph_set_font(ctx, font_big);
+  rl2_graph_draw_text(ctx, title, title_x, title_y, 0.0, 0.0, 0.0);
 // class labels output
   p = ChartData.GetFirst();
   while (p)
     {
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, p->GetValue().ToUTF8());
       if (strlen(text) > 10)
         {
@@ -2058,22 +2171,23 @@ void StatsChartDialog::DoUniqueHistogram(int hsize, int vsize, int target,
           text[11] = '.';
           text[12] = '\0';      // truncating to max 10 chars
         }
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
-      gGraphDrawText(gr, text, base_x + (txtHeight / 2.0) + (step_x / 2.0),
-                     vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
+      rl2_graph_draw_text(ctx, text,
+                          base_x + (txtHeight / 2.0) + (step_x / 2.0),
+                          vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
       base_x += step_x;
       p = p->GetNext();
     }
   if (others)
     {
       // including the 'any other' class
-      gGraphSetFont(gr, font);
-      gGraphGetTextExtent(gr, "AnyOther", &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
-      gGraphDrawText(gr, "AnyOther",
-                     base_x + (txtHeight / 2.0) + (step_x / 2.0),
-                     vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+      rl2_graph_set_font(ctx, font);
+      rl2_graph_get_text_extent(ctx, "AnyOther", &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
+      rl2_graph_draw_text(ctx, "AnyOther",
+                          base_x + (txtHeight / 2.0) + (step_x / 2.0),
+                          vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
     }
 
   idx = 0;
@@ -2081,13 +2195,15 @@ void StatsChartDialog::DoUniqueHistogram(int hsize, int vsize, int target,
   p = ChartData.GetFirst();
   while (p)
     {
-      gGraphSetPen(gr, 0, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
+      rl2_graph_set_solid_pen(ctx, 0, 0, 0, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
       color_idx = idx % 8;
-      gGraphSetBrush(gr, colors[color_idx].Red(), colors[color_idx].Green(),
-                     colors[color_idx].Blue(), 255);
+      rl2_graph_set_brush(ctx, colors[color_idx].Red(),
+                          colors[color_idx].Green(), colors[color_idx].Blue(),
+                          255);
       height =
         vspan * ((double) (p->GetCount() / (double) (ChartData.GetMaxFreq())));
-      gGraphDrawRectangle(gr, base_x, base_y - height, step_x, height);
+      rl2_graph_draw_rectangle(ctx, base_x, base_y - height, step_x, height);
       base_x += step_x;
       idx++;
       p = p->GetNext();
@@ -2096,75 +2212,88 @@ void StatsChartDialog::DoUniqueHistogram(int hsize, int vsize, int target,
     {
       // other unclassified values
       color_idx = idx % 8;
-      gGraphSetBrush(gr, colors[color_idx].Red(), colors[color_idx].Green(),
-                     colors[color_idx].Blue(), 255);
+      rl2_graph_set_brush(ctx, colors[color_idx].Red(),
+                          colors[color_idx].Green(), colors[color_idx].Blue(),
+                          255);
       height =
         vspan *
         ((double)
          (ChartData.GetOtherUniquesFreq() / (double) (ChartData.GetMaxFreq())));
-      gGraphDrawRectangle(gr, base_x, base_y - height, step_x, height);
+      rl2_graph_draw_rectangle(ctx, base_x, base_y - height, step_x, height);
     }
 // drawing 'scale' labels
   pLab = scaleLabels.GetFirst();
   while (pLab)
     {
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, pLab->GetLabel().ToUTF8());
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
-      gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
-                     base_y - pLab->GetPosition() + (txtHeight / 2.0), 0.0);
-      gGraphSetPen(gr, 255, 128, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
-      gGraphStrokeLine(gr, start_x, base_y - pLab->GetPosition(), end_x,
-                       base_y - pLab->GetPosition());
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
+      rl2_graph_draw_text(ctx, text, scaleWidth - txtWidth + 5,
+                          base_y - pLab->GetPosition() + (txtHeight / 2.0),
+                          0.0, 0.0, 0.0);
+      rl2_graph_set_solid_pen(ctx, 255, 128, 128, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
+      rl2_graph_stroke_line(ctx, start_x, base_y - pLab->GetPosition(), end_x,
+                            base_y - pLab->GetPosition());
       pLab = pLab->GetNext();
     }
 // marking the ZERO baseline
-  gGraphSetFont(gr, font);
+  rl2_graph_set_font(ctx, font);
   strcpy(text, "0");
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
-                 base_y + (txtHeight / 2.0), 0.0);
-  gGraphSetPen(gr, 255, 128, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
-  gGraphStrokeLine(gr, start_x, base_y, end_x, base_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, scaleWidth - txtWidth + 5,
+                      base_y + (txtHeight / 2.0), 0.0, 0.0, 0.0);
+  rl2_graph_set_solid_pen(ctx, 255, 128, 128, 255, 1, RL2_PEN_CAP_ROUND,
+                          RL2_PEN_JOIN_ROUND);
+  rl2_graph_stroke_line(ctx, start_x, base_y, end_x, base_y);
 
 // graphics finalization
-  gGraphDestroyFont(font);
-  gGraphDestroyFont(font_big);
+  rl2_graph_destroy_font(font);
+  rl2_graph_destroy_font(font_big);
   if (target == CHART_TARGET_IS_COPY || target == CHART_TARGET_IS_PNG
       || target == CHART_TARGET_IS_PREVIEW)
-    gGraphGetContextRgbArray(gr, &rgb_array);
-  if (target == CHART_TARGET_IS_SVG)
-    gGraphDestroySvgContext(gr);
-  else if (target == CHART_TARGET_IS_PDF)
-    gGraphDestroyPdfContext(gr);
-  else
-    gGraphDestroyContext(gr);
+    rgb_array = rl2_graph_get_context_rgb_array(ctx);
+  if (ctx != NULL)
+    rl2_graph_destroy_context(ctx);
 
+done:
   if (target == CHART_TARGET_IS_PNG)
     {
       if (rgb_array)
         {
           // creating the Image from RGB array
-          const void *img =
-            gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
-          if (img)
+          int err = 1;
+          unsigned char *png;
+          int png_size;
+          if (rl2_rgb_to_png(hsize, vsize, rgb_array, &png, &png_size) ==
+              RL2_OK)
             {
               char xpath[2024];
               strcpy(xpath, ExportPath.ToUTF8());
-              if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
+              FILE *out = fopen(xpath, "wb");
+              if (out == NULL)
+                err = 1;
+              else
                 {
-                  wxString msg =
-                    wxT
-                    ("An error occurred while saving\nthe current Char as PNG");
-                  wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
-                               MainFrame);
+                  int wr = fwrite(png, 1, png_size, out);
+                  if (wr == png_size)
+                    err = 0;
+                  fclose(out);
                 }
-              gGraphDestroyImage(img);
+              free(rgb_array);
+            }
+          if (err)
+            {
+              wxString msg =
+                wxT("An error occurred while saving\nthe current Chart as PNG");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
+                           MainFrame);
             }
         }
     }
+
   if (target == CHART_TARGET_IS_PREVIEW)
     {
       if (rgb_array)
@@ -2197,9 +2326,9 @@ void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
 {
 // generating a Line Chart (Unique values)
   unsigned char *rgb_array = NULL;
-  const void *gr = NULL;
-  const void *font = NULL;
-  const void *font_big = NULL;
+  rl2GraphicsContextPtr ctx = NULL;
+  rl2GraphicsFontPtr font = NULL;
+  rl2GraphicsFontPtr font_big = NULL;
   int idx;
   MyChartUniqueClass *p;
   int start_x;
@@ -2235,27 +2364,44 @@ void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
+      ctx = rl2_graph_create_svg_context(xpath, hsize, vsize);
   } else if (target == CHART_TARGET_IS_PDF)
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
-                             &gr);
+      // assuming A4 300 DPI
+      double pageWidth = 8.3;
+      double pageHeight = 11.7;
+      if (hsize > vsize)
+        {
+          // landscape
+          pageWidth = 11.7;
+          pageHeight = 8.3;
+        }
+      double pdf_hsize = (pageWidth - 2.0) * 300.0;
+      double pdf_vsize = (pageHeight - 2.0) * 300.0;
+      hsize = (int) pdf_hsize;
+      vsize = (int) pdf_vsize;
+      ctx =
+        rl2_graph_create_pdf_context(xpath, 300, pageWidth, pageHeight, 1, 1);
   } else
-    gGraphCreateContext(hsize, vsize, &gr);
+    ctx = rl2_graph_create_context(hsize, vsize);
+  if (ctx == NULL)
+    goto done;
 
 // background initialization
-  gGraphSetBrush(gr, 255, 255, 255, 255);
-  gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
+  rl2_graph_set_brush(ctx, 255, 255, 255, 255);
+  rl2_graph_draw_rectangle(ctx, -1, -1, hsize + 2, vsize + 2);
 
 // font setup
-  gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_NORMAL,
-                   &font);
-  gGraphFontSetColor(font, 0, 0, 0, 255);
-  gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_BOLD,
-                   &font_big);
-  gGraphFontSetColor(font_big, 0, 0, 0, 255);
+  font =
+    rl2_graph_create_toy_font(NULL, font_size, RL2_FONTSTYLE_NORMAL,
+                              RL2_FONTWEIGHT_NORMAL);
+  rl2_graph_font_set_color(font, 0, 0, 0, 255);
+  font_big =
+    rl2_graph_create_toy_font(NULL, font_size, RL2_FONTSTYLE_NORMAL,
+                              RL2_FONTWEIGHT_BOLD);
+  rl2_graph_font_set_color(font_big, 0, 0, 0, 255);
 
   if (ChartData.GetOtherUniquesFreq() > 0)
     others = 1;
@@ -2265,16 +2411,16 @@ void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
   MainFrame->DoubleQuotedSql(table);
   MainFrame->DoubleQuotedSql(column);
   sprintf(title, "Dataset: %s.%s     [unique values]", table, column);
-  gGraphSetFont(gr, font_big);
-  gGraphGetTextExtent(gr, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
-                      &post_x, &post_y);
+  rl2_graph_set_font(ctx, font_big);
+  rl2_graph_get_text_extent(ctx, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
+                            &post_x, &post_y);
   title_x = (hsize - (int) txtWidth) / 2;
   title_y = 5 + (int) titleHeight;
 // measuring class labels
   p = ChartData.GetFirst();
   while (p)
     {
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, p->GetValue().ToUTF8());
       if (strlen(text) > 10)
         {
@@ -2282,8 +2428,8 @@ void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
           text[11] = '.';
           text[12] = '\0';      // truncating to max 10 chars
         }
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
       if (txtWidth > labelWidth)
         labelWidth = txtWidth;
       p = p->GetNext();
@@ -2291,9 +2437,9 @@ void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
   if (others)
     {
       // including the 'any other' class
-      gGraphSetFont(gr, font);
-      gGraphGetTextExtent(gr, "AnyOther", &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
+      rl2_graph_set_font(ctx, font);
+      rl2_graph_get_text_extent(ctx, "AnyOther", &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
       if (txtWidth > labelWidth)
         labelWidth = txtWidth;
     }
@@ -2308,10 +2454,10 @@ void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
   pLab = scaleLabels.GetFirst();
   while (pLab)
     {
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, pLab->GetLabel().ToUTF8());
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
       if (txtWidth > scaleWidth)
         scaleWidth = txtWidth;
       pLab = pLab->GetNext();
@@ -2324,13 +2470,13 @@ void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
     (double) (end_x - start_x) / (double) (ChartData.GetNumClasses() + others);
 
 // title output
-  gGraphSetFont(gr, font_big);
-  gGraphDrawText(gr, title, title_x, title_y, 0.0);
+  rl2_graph_set_font(ctx, font_big);
+  rl2_graph_draw_text(ctx, title, title_x, title_y, 0.0, 0.0, 0.0);
 // class labels output
   p = ChartData.GetFirst();
   while (p)
     {
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, p->GetValue().ToUTF8());
       if (strlen(text) > 10)
         {
@@ -2338,22 +2484,23 @@ void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
           text[11] = '.';
           text[12] = '\0';      // truncating to max 10 chars
         }
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
-      gGraphDrawText(gr, text, base_x + (txtHeight / 2.0) + (step_x / 2.0),
-                     vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
+      rl2_graph_draw_text(ctx, text,
+                          base_x + (txtHeight / 2.0) + (step_x / 2.0),
+                          vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
       base_x += step_x;
       p = p->GetNext();
     }
   if (others)
     {
       // including the 'any other' class
-      gGraphSetFont(gr, font);
-      gGraphGetTextExtent(gr, "AnyOther", &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
-      gGraphDrawText(gr, "AnyOther",
-                     base_x + (txtHeight / 2.0) + (step_x / 2.0),
-                     vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
+      rl2_graph_set_font(ctx, font);
+      rl2_graph_get_text_extent(ctx, "AnyOther", &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
+      rl2_graph_draw_text(ctx, "AnyOther",
+                          base_x + (txtHeight / 2.0) + (step_x / 2.0),
+                          vsize - labelWidth + txtWidth - 5, 90, 0.0, 0.0);
     }
 
   idx = 0;
@@ -2363,9 +2510,10 @@ void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
     {
       height =
         vspan * ((double) (p->GetCount() / (double) (ChartData.GetMaxFreq())));
-      gGraphSetPen(gr, 192, 192, 192, 255, 1, GGRAPH_PENSTYLE_DOT);
-      gGraphStrokeLine(gr, base_x + (step_x / 2.0), start_y,
-                       base_x + (step_x / 2.0), base_y - height);
+      rl2_graph_set_solid_pen(ctx, 192, 192, 192, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
+      rl2_graph_stroke_line(ctx, base_x + (step_x / 2.0), start_y,
+                            base_x + (step_x / 2.0), base_y - height);
       base_x += step_x;
       idx++;
       p = p->GetNext();
@@ -2377,8 +2525,8 @@ void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
         vspan *
         ((double)
          (ChartData.GetOtherUniquesFreq() / (double) (ChartData.GetMaxFreq())));
-      gGraphStrokeLine(gr, base_x + (step_x / 2.0), start_y,
-                       base_x + (step_x / 2.0), base_y - height);
+      rl2_graph_stroke_line(ctx, base_x + (step_x / 2.0), start_y,
+                            base_x + (step_x / 2.0), base_y - height);
     }
   idx = 0;
   base_x = start_x;
@@ -2388,9 +2536,10 @@ void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
       height =
         vspan * ((double) (p->GetCount() / (double) (ChartData.GetMaxFreq())));
       if (idx == 0)
-        gGraphMoveToPoint(gr, base_x + (step_x / 2.0), base_y - height);
+        rl2_graph_move_to_point(ctx, base_x + (step_x / 2.0), base_y - height);
       else
-        gGraphAddLineToPath(gr, base_x + (step_x / 2.0), base_y - height);
+        rl2_graph_add_line_to_path(ctx, base_x + (step_x / 2.0),
+                                   base_y - height);
       base_x += step_x;
       idx++;
       p = p->GetNext();
@@ -2402,72 +2551,85 @@ void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
         vspan *
         ((double)
          (ChartData.GetOtherUniquesFreq() / (double) (ChartData.GetMaxFreq())));
-      gGraphAddLineToPath(gr, base_x + (step_x / 2.0), base_y - height);
+      rl2_graph_add_line_to_path(ctx, base_x + (step_x / 2.0), base_y - height);
     }
-  gGraphSetPen(gr, 255, 0, 0, 255, 2, GGRAPH_PENSTYLE_SOLID);
-  gGraphStrokePath(gr, GGRAPH_CLEAR_PATH);
+  rl2_graph_set_solid_pen(ctx, 255, 0, 0, 255, 2, RL2_PEN_CAP_ROUND,
+                          RL2_PEN_JOIN_ROUND);
+  rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
 
 // drawing 'scale' labels
   pLab = scaleLabels.GetFirst();
   while (pLab)
     {
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, pLab->GetLabel().ToUTF8());
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
-      gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
-                     base_y - pLab->GetPosition() + (txtHeight / 2.0), 0.0);
-      gGraphSetPen(gr, 128, 255, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
-      gGraphStrokeLine(gr, start_x, base_y - pLab->GetPosition(), end_x,
-                       base_y - pLab->GetPosition());
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
+      rl2_graph_draw_text(ctx, text, scaleWidth - txtWidth + 5,
+                          base_y - pLab->GetPosition() + (txtHeight / 2.0),
+                          0.0, 0.0, 0.0);
+      rl2_graph_set_solid_pen(ctx, 128, 255, 128, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
+      rl2_graph_stroke_line(ctx, start_x, base_y - pLab->GetPosition(), end_x,
+                            base_y - pLab->GetPosition());
       pLab = pLab->GetNext();
     }
 // marking the ZERO baseline
-  gGraphSetFont(gr, font);
+  rl2_graph_set_font(ctx, font);
   strcpy(text, "0");
-  gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
-                      &post_y);
-  gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
-                 base_y + (txtHeight / 2.0), 0.0);
-  gGraphSetPen(gr, 128, 255, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
-  gGraphStrokeLine(gr, start_x, base_y, end_x, base_y);
+  rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
+                            &post_x, &post_y);
+  rl2_graph_draw_text(ctx, text, scaleWidth - txtWidth + 5,
+                      base_y + (txtHeight / 2.0), 0.0, 0.0, 0.0);
+  rl2_graph_set_solid_pen(ctx, 128, 255, 128, 255, 1, RL2_PEN_CAP_ROUND,
+                          RL2_PEN_JOIN_ROUND);
+  rl2_graph_stroke_line(ctx, start_x, base_y, end_x, base_y);
 
 // graphics finalization
-  gGraphDestroyFont(font);
-  gGraphDestroyFont(font_big);
+  rl2_graph_destroy_font(font);
+  rl2_graph_destroy_font(font_big);
   if (target == CHART_TARGET_IS_COPY || target == CHART_TARGET_IS_PNG
       || target == CHART_TARGET_IS_PREVIEW)
-    gGraphGetContextRgbArray(gr, &rgb_array);
-  if (target == CHART_TARGET_IS_SVG)
-    gGraphDestroySvgContext(gr);
-  else if (target == CHART_TARGET_IS_PDF)
-    gGraphDestroyPdfContext(gr);
-  else
-    gGraphDestroyContext(gr);
+    rgb_array = rl2_graph_get_context_rgb_array(ctx);
+  if (ctx != NULL)
+    rl2_graph_destroy_context(ctx);
 
+done:
   if (target == CHART_TARGET_IS_PNG)
     {
       if (rgb_array)
         {
           // creating the Image from RGB array
-          const void *img =
-            gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
-          if (img)
+          int err = 1;
+          unsigned char *png;
+          int png_size;
+          if (rl2_rgb_to_png(hsize, vsize, rgb_array, &png, &png_size) ==
+              RL2_OK)
             {
               char xpath[2024];
               strcpy(xpath, ExportPath.ToUTF8());
-              if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
+              FILE *out = fopen(xpath, "wb");
+              if (out == NULL)
+                err = 1;
+              else
                 {
-                  wxString msg =
-                    wxT
-                    ("An error occurred while saving\nthe current Char as PNG");
-                  wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
-                               MainFrame);
+                  int wr = fwrite(png, 1, png_size, out);
+                  if (wr == png_size)
+                    err = 0;
+                  fclose(out);
                 }
-              gGraphDestroyImage(img);
+              free(rgb_array);
+            }
+          if (err)
+            {
+              wxString msg =
+                wxT("An error occurred while saving\nthe current Chart as PNG");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
+                           MainFrame);
             }
         }
     }
+
   if (target == CHART_TARGET_IS_PREVIEW)
     {
       if (rgb_array)
@@ -2500,9 +2662,9 @@ void StatsChartDialog::DoUniquePieChart(int hsize, int vsize, int target,
 {
 // generating a Pie Chart (Unique values)
   unsigned char *rgb_array = NULL;
-  const void *gr = NULL;
-  const void *font = NULL;
-  const void *font_big = NULL;
+  rl2GraphicsContextPtr ctx = NULL;
+  rl2GraphicsFontPtr font = NULL;
+  rl2GraphicsFontPtr font_big = NULL;
   int idx;
   MyChartUniqueClass *p;
   double radius_x;
@@ -2551,27 +2713,44 @@ void StatsChartDialog::DoUniquePieChart(int hsize, int vsize, int target,
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
+      ctx = rl2_graph_create_svg_context(xpath, hsize, vsize);
   } else if (target == CHART_TARGET_IS_PDF)
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
-                             &gr);
+      // assuming A4 300 DPI
+      double pageWidth = 8.3;
+      double pageHeight = 11.7;
+      if (hsize > vsize)
+        {
+          // landscape
+          pageWidth = 11.7;
+          pageHeight = 8.3;
+        }
+      double pdf_hsize = (pageWidth - 2.0) * 300.0;
+      double pdf_vsize = (pageHeight - 2.0) * 300.0;
+      hsize = (int) pdf_hsize;
+      vsize = (int) pdf_vsize;
+      ctx =
+        rl2_graph_create_pdf_context(xpath, 300, pageWidth, pageHeight, 1, 1);
   } else
-    gGraphCreateContext(hsize, vsize, &gr);
+    ctx = rl2_graph_create_context(hsize, vsize);
+  if (ctx == NULL)
+    goto done;
 
 // background initialization
-  gGraphSetBrush(gr, 255, 255, 255, 255);
-  gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
+  rl2_graph_set_brush(ctx, 255, 255, 255, 255);
+  rl2_graph_draw_rectangle(ctx, -1, -1, hsize + 2, vsize + 2);
 
 // font setup
-  gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_NORMAL,
-                   &font);
-  gGraphFontSetColor(font, 0, 0, 0, 255);
-  gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_BOLD,
-                   &font_big);
-  gGraphFontSetColor(font_big, 0, 0, 0, 255);
+  font =
+    rl2_graph_create_toy_font(NULL, font_size, RL2_FONTSTYLE_NORMAL,
+                              RL2_FONTWEIGHT_NORMAL);
+  rl2_graph_font_set_color(font, 0, 0, 0, 255);
+  font_big =
+    rl2_graph_create_toy_font(NULL, font_size, RL2_FONTSTYLE_NORMAL,
+                              RL2_FONTWEIGHT_BOLD);
+  rl2_graph_font_set_color(font_big, 0, 0, 0, 255);
 
   if (ChartData.GetOtherUniquesFreq() > 0)
     others = 1;
@@ -2581,16 +2760,16 @@ void StatsChartDialog::DoUniquePieChart(int hsize, int vsize, int target,
   MainFrame->DoubleQuotedSql(table);
   MainFrame->DoubleQuotedSql(column);
   sprintf(title, "Dataset: %s.%s     [unique values]", table, column);
-  gGraphSetFont(gr, font_big);
-  gGraphGetTextExtent(gr, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
-                      &post_x, &post_y);
+  rl2_graph_set_font(ctx, font_big);
+  rl2_graph_get_text_extent(ctx, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
+                            &post_x, &post_y);
   title_x = (hsize - (int) txtWidth) / 2;
   title_y = 5 + (int) titleHeight;
   p = ChartData.GetFirst();
   while (p)
     {
       // measuring labels
-      gGraphSetFont(gr, font);
+      rl2_graph_set_font(ctx, font);
       strcpy(text, p->GetValue().ToUTF8());
       if (strlen(text) > 10)
         {
@@ -2598,16 +2777,16 @@ void StatsChartDialog::DoUniquePieChart(int hsize, int vsize, int target,
           text[11] = '.';
           text[12] = '\0';      // truncating to max 10 chars
         }
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
       if (txtWidth > labelWidth)
         labelWidth = txtWidth;
       p = p->GetNext();
     }
   if (others)
     {
-      gGraphGetTextExtent(gr, "AnyOther", &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
+      rl2_graph_get_text_extent(ctx, "AnyOther", &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
       if (txtWidth > labelWidth)
         labelWidth = txtWidth;
     }
@@ -2624,22 +2803,24 @@ void StatsChartDialog::DoUniquePieChart(int hsize, int vsize, int target,
     radius = radius_y;
 
 // title output
-  gGraphSetFont(gr, font_big);
-  gGraphDrawText(gr, title, title_x, title_y, 0.0);
+  rl2_graph_set_font(ctx, font_big);
+  rl2_graph_draw_text(ctx, title, title_x, title_y, 0.0, 0.0, 0.0);
 
   from = 0.0;
   idx = 0;
   p = ChartData.GetFirst();
   while (p)
     {
-      gGraphSetPen(gr, 0, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
+      rl2_graph_set_solid_pen(ctx, 0, 0, 0, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
       color_idx = idx % 8;
-      gGraphSetBrush(gr, colors[color_idx].Red(), colors[color_idx].Green(),
-                     colors[color_idx].Blue(), 255);
+      rl2_graph_set_brush(ctx, colors[color_idx].Red(),
+                          colors[color_idx].Green(), colors[color_idx].Blue(),
+                          255);
       step =
         (M_PI * 2.0) *
         ((double) (p->GetCount() / (double) (ChartData.GetTotFreq())));
-      gGraphDrawCircleSector(gr, cx, cy, radius, from, from + step);
+      rl2_graph_draw_circle_sector(ctx, cx, cy, radius, from, from + step);
       strcpy(text, p->GetValue().ToUTF8());
       if (strlen(text) > 10)
         {
@@ -2658,13 +2839,14 @@ void StatsChartDialog::DoUniquePieChart(int hsize, int vsize, int target,
     {
       // other unclassified values
       color_idx = idx % 8;
-      gGraphSetBrush(gr, colors[color_idx].Red(), colors[color_idx].Green(),
-                     colors[color_idx].Blue(), 255);
+      rl2_graph_set_brush(ctx, colors[color_idx].Red(),
+                          colors[color_idx].Green(), colors[color_idx].Blue(),
+                          255);
       step =
         (M_PI * 2.0) *
         ((double)
          (ChartData.GetOtherUniquesFreq() / (double) (ChartData.GetTotFreq())));
-      gGraphDrawCircleSector(gr, cx, cy, radius, from, from + step);
+      rl2_graph_draw_circle_sector(ctx, cx, cy, radius, from, from + step);
       lx = cx + (radius * 0.90) * cos(from + (step / 2.0));
       ly = cy + (radius * 0.90) * sin(from + (step / 2.0));
       labels.Add("AnyOther", lx, ly);
@@ -2678,12 +2860,15 @@ void StatsChartDialog::DoUniquePieChart(int hsize, int vsize, int target,
       // printing Left labels
       pLab = labels.GetLeftLabel(idx);
       strcpy(text, pLab->GetLabel().ToUTF8());
-      gGraphSetFont(gr, font);
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
-      gGraphDrawText(gr, text, 10, base_y + (txtHeight / 2.0), 0.0);
-      gGraphSetPen(gr, 255, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
-      gGraphStrokeLine(gr, 10 + txtWidth, base_y, pLab->GetX(), pLab->GetY());
+      rl2_graph_set_font(ctx, font);
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
+      rl2_graph_draw_text(ctx, text, 10, base_y + (txtHeight / 2.0), 0.0, 0.0,
+                          0.0);
+      rl2_graph_set_solid_pen(ctx, 255, 0, 0, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
+      rl2_graph_stroke_line(ctx, 10 + txtWidth, base_y, pLab->GetX(),
+                            pLab->GetY());
       base_y += step_y;
     }
   step_y = (double) (vsize - 50) / (double) (labels.GetNumRightLabels() - 1);
@@ -2693,53 +2878,63 @@ void StatsChartDialog::DoUniquePieChart(int hsize, int vsize, int target,
       // printing Right labels
       pLab = labels.GetRightLabel(idx);
       strcpy(text, pLab->GetLabel().ToUTF8());
-      gGraphSetFont(gr, font);
-      gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
-                          &post_x, &post_y);
-      gGraphDrawText(gr, text, hsize - txtWidth - 10,
-                     base_y + (txtHeight / 2.0), 0.0);
-      gGraphSetPen(gr, 255, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
-      gGraphStrokeLine(gr, hsize - txtWidth - 10, base_y, pLab->GetX(),
-                       pLab->GetY());
+      rl2_graph_set_font(ctx, font);
+      rl2_graph_get_text_extent(ctx, text, &pre_x, &pre_y, &txtWidth,
+                                &txtHeight, &post_x, &post_y);
+      rl2_graph_draw_text(ctx, text, hsize - txtWidth - 10,
+                          base_y + (txtHeight / 2.0), 0.0, 0.0, 0.0);
+      rl2_graph_set_solid_pen(ctx, 255, 0, 0, 255, 1, RL2_PEN_CAP_ROUND,
+                              RL2_PEN_JOIN_ROUND);
+      rl2_graph_stroke_line(ctx, hsize - txtWidth - 10, base_y, pLab->GetX(),
+                            pLab->GetY());
       base_y += step_y;
     }
 
 // graphics finalization
-  gGraphDestroyFont(font);
-  gGraphDestroyFont(font_big);
+  rl2_graph_destroy_font(font);
+  rl2_graph_destroy_font(font_big);
   if (target == CHART_TARGET_IS_COPY || target == CHART_TARGET_IS_PNG
       || target == CHART_TARGET_IS_PREVIEW)
-    gGraphGetContextRgbArray(gr, &rgb_array);
-  if (target == CHART_TARGET_IS_SVG)
-    gGraphDestroySvgContext(gr);
-  else if (target == CHART_TARGET_IS_PDF)
-    gGraphDestroyPdfContext(gr);
-  else
-    gGraphDestroyContext(gr);
+    rgb_array = rl2_graph_get_context_rgb_array(ctx);
+  if (ctx != NULL)
+    rl2_graph_destroy_context(ctx);
 
+done:
   if (target == CHART_TARGET_IS_PNG)
     {
       if (rgb_array)
         {
           // creating the Image from RGB array
-          const void *img =
-            gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
-          if (img)
+          int err = 1;
+          unsigned char *png;
+          int png_size;
+          if (rl2_rgb_to_png(hsize, vsize, rgb_array, &png, &png_size) ==
+              RL2_OK)
             {
               char xpath[2024];
               strcpy(xpath, ExportPath.ToUTF8());
-              if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
+              FILE *out = fopen(xpath, "wb");
+              if (out == NULL)
+                err = 1;
+              else
                 {
-                  wxString msg =
-                    wxT
-                    ("An error occurred while saving\nthe current Char as PNG");
-                  wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
-                               MainFrame);
+                  int wr = fwrite(png, 1, png_size, out);
+                  if (wr == png_size)
+                    err = 0;
+                  fclose(out);
                 }
-              gGraphDestroyImage(img);
+              free(rgb_array);
+            }
+          if (err)
+            {
+              wxString msg =
+                wxT("An error occurred while saving\nthe current Chart as PNG");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
+                           MainFrame);
             }
         }
     }
+
   if (target == CHART_TARGET_IS_PREVIEW)
     {
       if (rgb_array)
@@ -3073,7 +3268,7 @@ void MapPreviewDialog::UpdatePreview()
 void MapPreviewDialog::DoMap(int hsize, int vsize, int target)
 {
 // drawing the map preview
-  const void *gr = NULL;
+  rl2GraphicsContextPtr ctx = NULL;
   unsigned char *rgb_array = NULL;
   char table[1024];
   char column[1024];
@@ -3094,23 +3289,56 @@ void MapPreviewDialog::DoMap(int hsize, int vsize, int target)
   int thickness;
 
 // computing the rendering ratio
-  if (ext_x > ext_y)
+  if (target == MAP_TARGET_IS_PDF)
     {
-      ratio = ext_x / (double) (hsize - 20);
-      if ((ext_y / ratio) > vsize)
-        ratio = ext_y / (double) (vsize - 20);
+      // assuming A4 portrait 300 DPI
+      double pageWidth = 8.3;
+      double pageHeight = 11.7;
+      if (ext_x > ext_y)
+        {
+          // landscape
+          pageWidth = 11.7;
+          pageHeight = 8.3;
+        }
+      double pdf_hsize = (pageWidth - 2.0) * 300.0;
+      double pdf_vsize = (pageHeight - 2.0) * 300.0;
+      hsize = (int) pdf_hsize;
+      vsize = (int) pdf_vsize;
+      if (ext_x > ext_y)
+        ratio = ext_x / pdf_hsize;
+      else
+        ratio = ext_y / pdf_vsize;
+      while (1)
+        {
+          horz = (int) (ext_x / ratio);
+          vert = (int) (ext_y / ratio);
+          if (horz < (pdf_hsize - 5) && vert < (pdf_vsize - 5))
+            break;
+          ratio *= 1.001;
+        }
+      horz = (int) (ext_x / ratio);
+      vert = (int) (ext_y / ratio);
+      h_shift = (pdf_hsize - horz) / 2;
+      v_shift = (pdf_vsize - vert) / 2;
   } else
     {
-      ratio = ext_y / (double) (vsize - 20);
-      if ((ext_x / ratio) > hsize)
-        ratio = ext_x / (double) (hsize - 20);
+      if (ext_x > ext_y)
+        ratio = ext_x / (double) hsize;
+      else
+        ratio = ext_y / (double) vsize;
+      while (1)
+        {
+          horz = (int) (ext_x / ratio);
+          vert = (int) (ext_y / ratio);
+          if (horz < (hsize - 5) && vert < (vsize - 5))
+            break;
+          ratio *= 1.001;
+        }
+      horz = (int) (ext_x / ratio);
+      vert = (int) (ext_y / ratio);
+      h_shift = (hsize - horz) / 2;
+      v_shift = (vsize - vert) / 2;
     }
-  horz = (int) (ext_x / ratio);
-  vert = (int) (ext_y / ratio);
-  horz += 20;
-  vert += 20;
-  h_shift = (hsize - horz) / 2;
-  v_shift = (vsize - vert) / 2;
 
 // retrieving current graphic settings
   switch (SymbolCtrl->GetSelection())
@@ -3133,30 +3361,42 @@ void MapPreviewDialog::DoMap(int hsize, int vsize, int target)
     };
   symbol_size = SymSizeCtrl->GetValue();
   thickness = ThicknessCtrl->GetValue();
-
 // graphics initialization
   if (target == MAP_TARGET_IS_SVG)
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
+      ctx = rl2_graph_create_svg_context(xpath, hsize, vsize);
   } else if (target == MAP_TARGET_IS_PDF)
     {
       char xpath[2024];
       strcpy(xpath, ExportPath.ToUTF8());
-      gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
-                             &gr);
+      // assuming A4 portrait 300 DPI
+      double pageWidth = 8.3;
+      double pageHeight = 11.7;
+      if (hsize > vsize)
+        {
+          // landscape
+          pageWidth = 11.7;
+          pageHeight = 8.3;
+        }
+      ctx =
+        rl2_graph_create_pdf_context(xpath, 300, pageWidth, pageHeight, 1, 1);
   } else
-    gGraphCreateContext(hsize, vsize, &gr);
+    ctx = rl2_graph_create_context(hsize, vsize);
+  if (ctx == NULL)
+    goto done;
 
 // background initialization
-  gGraphSetBrush(gr, 255, 255, 255, 255);
-  gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
+  rl2_graph_set_brush(ctx, 255, 255, 255, 255);
+  rl2_graph_draw_rectangle(ctx, -1, -1, hsize + 2, vsize + 2);
 
 // setting standard graphic setting
-  gGraphSetPen(gr, LineColor.Red(), LineColor.Green(), LineColor.Blue(), 255,
-               thickness, GGRAPH_PENSTYLE_SOLID);
-  gGraphSetBrush(gr, FillColor.Red(), FillColor.Green(), FillColor.Blue(), 255);
+  rl2_graph_set_solid_pen(ctx, LineColor.Red(), LineColor.Green(),
+                          LineColor.Blue(), 255, thickness, RL2_PEN_CAP_ROUND,
+                          RL2_PEN_JOIN_ROUND);
+  rl2_graph_set_brush(ctx, FillColor.Red(), FillColor.Green(), FillColor.Blue(),
+                      255);
 
   ::wxBeginBusyCursor();
   strcpy(table, Table.ToUTF8());
@@ -3239,7 +3479,7 @@ void MapPreviewDialog::DoMap(int hsize, int vsize, int target)
                           y += v_shift;
                           if (iv == 0)
                             {
-                              gGraphMoveToPoint(gr, x, y);
+                              rl2_graph_move_to_point(ctx, x, y);
                               lastX = x;
                               lastY = y;
                           } else
@@ -3248,13 +3488,13 @@ void MapPreviewDialog::DoMap(int hsize, int vsize, int target)
                                 ;
                               else
                                 {
-                                  gGraphAddLineToPath(gr, x, y);
+                                  rl2_graph_add_line_to_path(ctx, x, y);
                                   lastX = x;
                                   lastY = y;
                                 }
                             }
                         }
-                      gGraphCloseSubpath(gr);
+                      rl2_graph_close_subpath(ctx);
                       for (ib = 0; ib < pg->NumInteriors; ib++)
                         {
                           // interior borders
@@ -3283,7 +3523,7 @@ void MapPreviewDialog::DoMap(int hsize, int vsize, int target)
                               y += v_shift;
                               if (iv == 0)
                                 {
-                                  gGraphMoveToPoint(gr, x, y);
+                                  rl2_graph_move_to_point(ctx, x, y);
                                   lastX = x;
                                   lastY = y;
                               } else
@@ -3292,17 +3532,17 @@ void MapPreviewDialog::DoMap(int hsize, int vsize, int target)
                                     ;
                                   else
                                     {
-                                      gGraphAddLineToPath(gr, x, y);
+                                      rl2_graph_add_line_to_path(ctx, x, y);
                                       lastX = x;
                                       lastY = y;
                                     }
                                 }
                             }
-                          gGraphCloseSubpath(gr);
+                          rl2_graph_close_subpath(ctx);
                         }
                       if (fill == true)
-                        gGraphFillPath(gr, GGRAPH_PRESERVE_PATH);
-                      gGraphStrokePath(gr, GGRAPH_CLEAR_PATH);
+                        rl2_graph_fill_path(ctx, RL2_PRESERVE_PATH);
+                      rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
                       pg = pg->Next;
                     }
                   gaiaLinestringPtr ln = geom->FirstLinestring;
@@ -3340,7 +3580,7 @@ void MapPreviewDialog::DoMap(int hsize, int vsize, int target)
                           y += v_shift;
                           if (iv == 0)
                             {
-                              gGraphMoveToPoint(gr, x, y);
+                              rl2_graph_move_to_point(ctx, x, y);
                               lastX = x;
                               lastY = y;
                           } else
@@ -3349,13 +3589,13 @@ void MapPreviewDialog::DoMap(int hsize, int vsize, int target)
                                 ;
                               else
                                 {
-                                  gGraphAddLineToPath(gr, x, y);
+                                  rl2_graph_add_line_to_path(ctx, x, y);
                                   lastX = x;
                                   lastY = y;
                                 }
                             }
                         }
-                      gGraphStrokePath(gr, GGRAPH_CLEAR_PATH);
+                      rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
                       ln = ln->Next;
                     }
                   gaiaPointPtr pt = geom->FirstPoint;
@@ -3363,16 +3603,18 @@ void MapPreviewDialog::DoMap(int hsize, int vsize, int target)
                     {
                       // drawing a POINT
                       x = (int) ((pt->X - MinX) / ratio);
-                      y = vsize - (int) ((pt->Y - MinY) / ratio);
+                      y = vert - (int) ((pt->Y - MinY) / ratio);
                       x += h_shift;
                       y += v_shift;
                       if (circle == false)
-                        gGraphDrawRectangle(gr, x - symbol_size,
-                                            y - symbol_size, symbol_size * 2,
-                                            symbol_size * 2);
+                        rl2_graph_draw_rectangle(ctx, x - symbol_size,
+                                                 y - symbol_size,
+                                                 symbol_size * 2,
+                                                 symbol_size * 2);
                       else
-                        gGraphDrawEllipse(gr, x - symbol_size, y - symbol_size,
-                                          symbol_size * 2, symbol_size * 2);
+                        rl2_graph_draw_ellipse(ctx, x - symbol_size,
+                                               y - symbol_size, symbol_size * 2,
+                                               symbol_size * 2);
                       pt = pt->Next;
                     }
                   gaiaFreeGeomColl(geom);
@@ -3395,34 +3637,43 @@ void MapPreviewDialog::DoMap(int hsize, int vsize, int target)
 // graphics finalization
   if (target == MAP_TARGET_IS_COPY || target == MAP_TARGET_IS_PNG
       || target == MAP_TARGET_IS_PREVIEW)
-    gGraphGetContextRgbArray(gr, &rgb_array);
-  if (target == MAP_TARGET_IS_SVG)
-    gGraphDestroySvgContext(gr);
-  else if (target == MAP_TARGET_IS_PDF)
-    gGraphDestroyPdfContext(gr);
-  else
-    gGraphDestroyContext(gr);
+    rgb_array = rl2_graph_get_context_rgb_array(ctx);
+  if (ctx != NULL)
+    rl2_graph_destroy_context(ctx);
 
+done:
   if (target == MAP_TARGET_IS_PNG)
     {
       if (rgb_array)
         {
           // creating the Image from RGB array
-          const void *img =
-            gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
-          if (img)
+          int err = 1;
+          unsigned char *png;
+          int png_size;
+          if (rl2_rgb_to_png(hsize, vsize, rgb_array, &png, &png_size) ==
+              RL2_OK)
             {
               char xpath[2024];
               strcpy(xpath, ExportPath.ToUTF8());
-              if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
+              FILE *out = fopen(xpath, "wb");
+              if (out == NULL)
+                err = 1;
+              else
                 {
-                  wxString msg =
-                    wxT
-                    ("An error occurred while saving\nthe current Map as PNG");
-                  wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
-                               MainFrame);
+                  int wr = fwrite(png, 1, png_size, out);
+                  if (wr == png_size)
+                    err = 0;
+                  fclose(out);
                 }
-              gGraphDestroyImage(img);
+              free(rgb_array);
+              free(png);
+            }
+          if (err)
+            {
+              wxString msg =
+                wxT("An error occurred while saving\nthe current Map as PNG");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
+                           MainFrame);
             }
         }
     }
diff --git a/Exif.cpp b/Exif.cpp
index 04e0231..a70923c 100644
--- a/Exif.cpp
+++ b/Exif.cpp
@@ -1908,7 +1908,7 @@ int MyFrame::XmlDocumentLoadFile(wxString & path, int compressed,
         {
           // attempting to retrieve an internally defined SchemaURI
           char *internalSchemaURI =
-            gaiaXmlGetInternalSchemaURI(InternalCache, blob, rd);
+            gaiaXmlGetInternalSchemaURI(SpliteInternalCache, blob, rd);
           if (internalSchemaURI == NULL)
             {
               // unable to identify the SchemaURI
@@ -1919,7 +1919,7 @@ int MyFrame::XmlDocumentLoadFile(wxString & path, int compressed,
               len = strlen(internalSchemaURI);
               p_schemaURI = (char *) malloc(len + 1);
               strcpy(p_schemaURI, internalSchemaURI);
-              gaiaXmlToBlob(InternalCache, blob, rd, compressed,
+              gaiaXmlToBlob(SpliteInternalCache, blob, rd, compressed,
                             internalSchemaURI, (unsigned char **) (&xml),
                             &xml_size, &parseError, &validateError);
               free(internalSchemaURI);
@@ -1933,7 +1933,7 @@ int MyFrame::XmlDocumentLoadFile(wxString & path, int compressed,
               p_schemaURI = (char *) malloc(len + 1);
               strcpy(p_schemaURI, schemaURI);
             }
-          gaiaXmlToBlob(InternalCache, blob, rd, compressed, schemaURI,
+          gaiaXmlToBlob(SpliteInternalCache, blob, rd, compressed, schemaURI,
                         (unsigned char **) (&xml), &xml_size, &parseError,
                         &validateError);
         }
@@ -2083,7 +2083,6 @@ int MyFrame::DxfLoadFile(wxString & path, wxString & prefix, wxString & layer,
   char selected_layer[1024];
   const char *xselected_layer = NULL;
   gaiaDxfParserPtr dxf;
-  bool error = false;
 
   *failed = 0;
 // creating a DXF parser
@@ -2115,7 +2114,7 @@ int MyFrame::DxfLoadFile(wxString & path, wxString & prefix, wxString & layer,
     }
 // attempting to parse the DXF input file
   strcpy(dxf_path, path.ToUTF8());
-  if (gaiaParseDxfFile(dxf, dxf_path))
+  if (gaiaParseDxfFile_r(GetSpliteInternalCache(), dxf, dxf_path))
     {
 // loading into the DB 
       int mode = GAIA_DXF_IMPORT_BY_LAYER;
diff --git a/Main.cpp b/Main.cpp
index 49c598e..4c347a1 100644
--- a/Main.cpp
+++ b/Main.cpp
@@ -2,11 +2,11 @@
 / Main.cpp
 / the main core of spatialite_gui  - a SQLite /SpatiaLite GUI tool
 /
-/ version 1.7, 2013 May 8
+/ version 1.7, 2014 May 8
 /
 / Author: Sandro Furieri a-furieri at lqt.it
 /
-/ Copyright (C) 2008-2013  Alessandro Furieri
+/ Copyright (C) 2008-2014  Alessandro Furieri
 /
 /    This program is free software: you can redistribute it and/or modify
 /    it under the terms of the GNU General Public License as published by
@@ -42,6 +42,7 @@
 #include "icons/icon_info.xpm"
 #include "icons/create_new.xpm"
 #include "icons/connect.xpm"
+#include "icons/connect_ro.xpm"
 #include "icons/disconnect.xpm"
 #include "icons/memdb_load.xpm"
 #include "icons/memdb_new.xpm"
@@ -73,6 +74,10 @@
 #include "icons/sanegeom.xpm"
 #include "icons/wfs.xpm"
 #include "icons/dxf.xpm"
+#include "icons/security_lock.xpm"
+#include "icons/security_relaxed.xpm"
+#include "icons/security_rdonly.xpm"
+#include "icons/coverage.xpm"
 
 
 #if defined(_WIN32) && !defined(__MINGW32__)
@@ -104,6 +109,13 @@ wxFrame((wxFrame *) NULL, -1, title, pos,
 //
 // main GUI frame constructor
 //
+  setlocale(LC_ALL, "");
+// forcing DECIMAL POINT IS COMMA
+  setlocale(LC_NUMERIC, "C");
+
+  Old_SPATIALITE_SECURITY_ENV = NULL;
+  RL2MaxThreads = 1;
+  wxImage::AddHandler(new wxPNGHandler);
   MemoryDatabase = false;
   AutoSaveInterval = 0;
   LastTotalChanges = 0;
@@ -281,9 +293,11 @@ wxFrame((wxFrame *) NULL, -1, title, pos,
 
   HelpPane = false;
   SqliteHandle = NULL;
-  InternalCache = NULL;
+  SpliteInternalCache = NULL;
+  RL2PrivateData = rl2_alloc_private();
   SqlitePath = wxT("");
   BtnConnect = new wxBitmap(connect_xpm);
+  BtnConnectReadOnly = new wxBitmap(connect_ro_xpm);
   BtnCreateNew = new wxBitmap(create_new_xpm);
   BtnDisconnect = new wxBitmap(disconnect_xpm);
   BtnMemDbLoad = new wxBitmap(memdb_load_xpm);
@@ -365,8 +379,8 @@ wxFrame((wxFrame *) NULL, -1, title, pos,
 //
 // setting up the status bar
 //
-  wxStatusBar *statusBar = new wxStatusBar(this);
-  SetStatusBar(statusBar);
+  StatusBar = new MyStatusBar(this);
+  SetStatusBar(StatusBar);
 
 //
 // setting up the menu bar
@@ -379,6 +393,11 @@ wxFrame((wxFrame *) NULL, -1, title, pos,
   menuItem->SetBitmap(*BtnConnect);
   menuFile->Append(menuItem);
   menuItem =
+    new wxMenuItem(menuFile, ID_Connect_RO,
+                   wxT("&Connecting an existing SQLite DB (Read Only)"));
+  menuItem->SetBitmap(*BtnConnectReadOnly);
+  menuFile->Append(menuItem);
+  menuItem =
     new wxMenuItem(menuFile, ID_CreateNew,
                    wxT("Creating a &New (empty) SQLite DB"));
   menuItem->SetBitmap(*BtnCreateNew);
@@ -506,6 +525,7 @@ wxFrame((wxFrame *) NULL, -1, title, pos,
   menuFile->AppendSeparator();
   menuItem = new wxMenuItem(menuFile, ID_Help, wxT("&Help"));
   menuItem->SetBitmap(*BtnHelp);
+  menuFile->Append(menuItem);
   menuItem = new wxMenuItem(menuFile, wxID_ABOUT, wxT("&About ..."));
   menuItem->SetBitmap(*BtnAbout);
   menuFile->Append(menuItem);
@@ -553,6 +573,10 @@ wxFrame((wxFrame *) NULL, -1, title, pos,
   toolBar->AddTool(ID_Connect, wxT("Connecting an existing SQLite DB"),
                    *BtnConnect, wxNullBitmap, wxITEM_NORMAL,
                    wxT("Connecting an existing SQLite DB"));
+  toolBar->AddTool(ID_Connect_RO,
+                   wxT("Connecting an existing SQLite DB (Read Only)"),
+                   *BtnConnectReadOnly, wxNullBitmap, wxITEM_NORMAL,
+                   wxT("Connecting an existing SQLite DB (Read Only)"));
   toolBar->AddTool(ID_CreateNew, wxT("Creating a &New (empty) SQLite DB"),
                    *BtnCreateNew, wxNullBitmap, wxITEM_NORMAL,
                    wxT("Creating a &New (empty) SQLite DB"));
@@ -684,6 +708,8 @@ wxFrame((wxFrame *) NULL, -1, title, pos,
 //
   Connect(ID_Connect, wxEVT_COMMAND_MENU_SELECTED,
           (wxObjectEventFunction) & MyFrame::OnConnect);
+  Connect(ID_Connect_RO, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyFrame::OnConnectReadOnly);
   Connect(ID_CreateNew, wxEVT_COMMAND_MENU_SELECTED,
           (wxObjectEventFunction) & MyFrame::OnCreateNew);
   Connect(ID_Disconnect, wxEVT_COMMAND_MENU_SELECTED,
@@ -782,14 +808,18 @@ MyFrame::~MyFrame()
   ConfigLayout = Manager.SavePerspective();
   GetPosition(&ConfigPaneX, &ConfigPaneY);
   GetSize(&ConfigPaneWidth, &ConfigPaneHeight);
-  SaveConfig();
-  Manager.UnInit();
+  DoUpdateRL2MaxThreads();
   if (SqliteHandle)
     sqlite3_close(SqliteHandle);
-  if (InternalCache)
-    spatialite_cleanup_ex(InternalCache);
+  if (SpliteInternalCache)
+    spatialite_cleanup_ex(SpliteInternalCache);
+  spatialite_shutdown();
+  SaveConfig();
+  Manager.UnInit();
   if (BtnConnect != NULL)
     delete BtnConnect;
+  if (BtnConnectReadOnly != NULL)
+    delete BtnConnectReadOnly;
   if (BtnCreateNew != NULL)
     delete BtnCreateNew;
   if (BtnDisconnect != NULL)
@@ -832,6 +862,12 @@ MyFrame::~MyFrame()
     delete BtnLoadXml;
   if (BtnSrids != NULL)
     delete BtnSrids;
+  if (BtnCharset != NULL)
+    delete BtnCharset;
+  if (BtnWFS != NULL)
+    delete BtnWFS;
+  if (BtnDXF != NULL)
+    delete BtnDXF;
   if (BtnHelp != NULL)
     delete BtnHelp;
   if (BtnAttach != NULL)
@@ -852,6 +888,8 @@ MyFrame::~MyFrame()
     delete[]Charsets;
   if (CharsetsNames)
     delete[]CharsetsNames;
+  if (RL2PrivateData)
+    rl2_cleanup_private(RL2PrivateData);
 }
 
 void MyFrame::SaveConfig()
@@ -868,6 +906,10 @@ void MyFrame::SaveConfig()
   config->Write(wxT("PaneHeight"), ConfigPaneHeight);
   config->Write(wxT("SqlitePath"), SqlitePath);
   config->Write(wxT("LastDirectory"), LastDirectory);
+  config->Write(wxT("WfsGetCapabilitiesURL"), WfsGetCapabilitiesURL);
+  config->Write(wxT("HttpProxy"), HttpProxy);
+  config->Write(wxT("ReadOnlyConnection"), ReadOnlyConnection);
+  config->Write(wxT("RL2MaxThreads"), RL2MaxThreads);
   delete config;
 }
 
@@ -887,6 +929,10 @@ void MyFrame::LoadConfig(wxString & externalPath)
   config->Read(wxT("PaneHeight"), &ConfigPaneHeight, -1);
   config->Read(wxT("SqlitePath"), &ConfigDbPath);
   config->Read(wxT("LastDirectory"), &ConfigDir);
+  config->Read(wxT("WfsGetCapabilitiesURL"), &WfsGetCapabilitiesURL);
+  config->Read(wxT("HttpProxy"), &HttpProxy);
+  config->Read(wxT("ReadOnlyConnection"), &ReadOnlyConnection);
+  config->Read(wxT("RL2MaxThreads"), &RL2MaxThreads);
   delete config;
   Hide();
   if (externalPath.Len() > 0)
@@ -906,13 +952,14 @@ void MyFrame::LoadConfig(wxString & externalPath)
   if (ConfigDbPath.Len() > 0)
     {
       SqlitePath = ConfigDbPath;
-      if (OpenDB() == false)
+      if (OpenDB(ReadOnlyConnection) == false)
         SqlitePath = wxT("");
       else
         {
           bool metadata = CheckMetadata();
           wxMenuBar *menuBar = GetMenuBar();
           menuBar->Enable(ID_Connect, false);
+          menuBar->Enable(ID_Connect_RO, false);
           menuBar->Enable(ID_MemoryDbLoad, false);
           menuBar->Enable(ID_MemoryDbNew, false);
           if (MemoryDatabase == true)
@@ -952,6 +999,7 @@ void MyFrame::LoadConfig(wxString & externalPath)
           menuBar->Check(ID_SqlLog, SqlLogEnabled);
           wxToolBar *toolBar = GetToolBar();
           toolBar->EnableTool(ID_Connect, false);
+          toolBar->EnableTool(ID_Connect_RO, false);
           toolBar->EnableTool(ID_MemoryDbLoad, false);
           toolBar->EnableTool(ID_MemoryDbNew, false);
           if (MemoryDatabase == true)
@@ -998,6 +1046,12 @@ void MyFrame::LoadConfig(wxString & externalPath)
                    this);
       AutoFDOmsg = wxT("");
     }
+  if (AutoGPKGmsg.Len() > 0)
+    {
+      wxMessageBox(AutoGPKGmsg, wxT("spatialite_gui"),
+                   wxOK | wxICON_INFORMATION, this);
+      AutoGPKGmsg = wxT("");
+    }
 }
 
 void MyFrame::OnQuit(wxCommandEvent & WXUNUSED(event))
@@ -1018,9 +1072,10 @@ void MyFrame::OnAttachDatabase(wxCommandEvent & WXUNUSED(event))
   wxString lastDir;
   wxString path;
   wxString suffixList =
-    wxT("SpatiaLite DB (*.sqlite;*.atlas)|*.sqlite;*.atlas|");
+    wxT("SpatiaLite DB (*.sqlite;*.atlas;*.gpkg)|*.sqlite;*.atlas;*.gpkg|");
   suffixList += wxT("SQLite DB (*.sqlite)|*.sqlite|");
   suffixList += wxT("LibreAtlas DB (*.atlas)|*.atlas|");
+  suffixList += wxT("OGC GeoPackage (*.gpkg)|*.gpkg|");
   suffixList += wxT("All files (*.*)|*.*");
   wxFileDialog fileDialog(this, wxT("Attach DataBase"),
                           wxT(""), wxT("db.sqlite"), suffixList,
@@ -1033,6 +1088,8 @@ void MyFrame::OnAttachDatabase(wxCommandEvent & WXUNUSED(event))
   if (ret == wxID_OK)
     {
       path = fileDialog.GetPath();
+      if (IsValidSqliteFile(path) == false)
+        return;
       if (DoAttachDatabase(path) == true)
         {
           wxFileName file(fileDialog.GetPath());
@@ -1043,6 +1100,69 @@ void MyFrame::OnAttachDatabase(wxCommandEvent & WXUNUSED(event))
     }
 }
 
+bool MyFrame::IsValidSqliteFile(wxString & db_path)
+{
+// checking the internal Magic Number
+  wxString msg = wxT("Unable to connect: ") + db_path;
+  bool ret = false;
+  char path[1024];
+  char magic[16];
+  FILE *in;
+  strcpy(path, db_path.ToUTF8());
+  in = fopen(path, "rb");
+  if (in == NULL)
+    {
+      msg += wxT("\n\nNot existing file or forbidden access");
+      wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      return false;
+    }
+  if (fread(magic, 1, 16, in) == 16)
+    {
+      int count = 0;
+      if (magic[0] == 0x53)
+        count++;
+      if (magic[1] == 0x51)
+        count++;
+      if (magic[2] == 0x4c)
+        count++;
+      if (magic[3] == 0x69)
+        count++;
+      if (magic[4] == 0x74)
+        count++;
+      if (magic[5] == 0x65)
+        count++;
+      if (magic[6] == 0x20)
+        count++;
+      if (magic[7] == 0x66)
+        count++;
+      if (magic[8] == 0x6f)
+        count++;
+      if (magic[9] == 0x72)
+        count++;
+      if (magic[10] == 0x6d)
+        count++;
+      if (magic[11] == 0x61)
+        count++;
+      if (magic[12] == 0x74)
+        count++;
+      if (magic[13] == 0x20)
+        count++;
+      if (magic[14] == 0x33)
+        count++;
+      if (magic[15] == 0x00)
+        count++;
+      if (count == 16)
+        ret = true;
+    }
+  fclose(in);
+  if (ret == false)
+    {
+      msg += wxT("\n\nNot a valid SQLite DB-file: invalid magic number");
+      wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+    }
+  return ret;
+}
+
 void MyFrame::EnableSqlLog()
 {
 //
@@ -1114,8 +1234,8 @@ void MyFrame::OnCheckGeometries(wxCommandEvent & WXUNUSED(event))
       ::wxBeginBusyCursor();
       int invalids;
       ret =
-        check_all_geometry_columns(GetSqlite(), output_dir, &invalids,
-                                   &err_msg);
+        check_all_geometry_columns_r(GetSpliteInternalCache(), GetSqlite(),
+                                     output_dir, &invalids, &err_msg);
       ::wxEndBusyCursor();
       if (ret == 0)
         {
@@ -1186,8 +1306,9 @@ void MyFrame::OnSanitizeGeometries(wxCommandEvent & WXUNUSED(event))
       ::wxBeginBusyCursor();
       int not_validated;
       ret =
-        sanitize_all_geometry_columns(GetSqlite(), tmp_prefix, output_dir,
-                                      &not_validated, &err_msg);
+        sanitize_all_geometry_columns_r(GetSpliteInternalCache(), GetSqlite(),
+                                        tmp_prefix, output_dir, &not_validated,
+                                        &err_msg);
       ::wxEndBusyCursor();
       if (ret == 0)
         {
@@ -1248,7 +1369,6 @@ void MyFrame::OnAbout(wxCommandEvent & WXUNUSED(event))
 //
 // ABOUT dialog - event handler
 //
-  bool has_libxml2 = false;
   char ver[128];
   wxAboutDialogInfo dlg;
   dlg.SetIcon(wxIcon(icon_info_xpm));
@@ -1260,6 +1380,8 @@ void MyFrame::OnAbout(wxCommandEvent & WXUNUSED(event))
   str += wxT("wxWidgets version ") + wxString::FromUTF8(ver) + wxT("\n");
   strcpy(ver, spatialite_version());
   str += wxT("SpatiaLite version ") + wxString::FromUTF8(ver) + wxT("\n");
+  strcpy(ver, rl2_version());
+  str += wxT("RasterLite2 version ") + wxString::FromUTF8(ver) + wxT("\n");
   strcpy(ver, sqlite3_libversion());
   str += wxT("SQLite version ") + wxString::FromUTF8(ver) + wxT("\n");
   strcpy(ver, GEOSversion());
@@ -1275,21 +1397,17 @@ void MyFrame::OnAbout(wxCommandEvent & WXUNUSED(event))
     {
       // printing out the LIBXML2 version if supported
       str += wxT("LIBXML2 version ") + wxString::FromUTF8(ver) + wxT("\n");
-      has_libxml2 = true;
-    }
-  str += wxT("\nSQLite's extension 'SpatiaLite' enabled\n");
-  str += wxT("SQLite's extension 'VirtualShape' enabled\n");
-  str += wxT("SQLite's extension 'VirtualDbf' enabled\n");
-  str += wxT("SQLite's extension 'VirtualXL' enabled\n");
-  str += wxT("SQLite's extension 'VirtualText' enabled\n");
-  if (has_libxml2)
-    str += wxT("SQLite's extension 'VirtualXPath' enabled\n");
-  str += wxT("SQLite's extension 'VirtualNetwork' enabled\n");
-  str += wxT("SQLite's extension 'RTree' enabled\n");
-  str += wxT("SQLite's extension 'MbrCache' enabled\n");
-  str += wxT("SQLite's extension 'VirtualFDO' enabled\n\n");
+    }
+  str +=
+    wxT("\nSQLite's extensions: 'SpatiaLite', 'VirtualShape', 'VirtualDbf',\n");
+  str += wxT("'VirtualXL', 'VirtualText', 'VirtualXPath', 'VirtualNetwork',\n");
+  str +=
+    wxT("'RTree', 'MbrCache', 'VirtualBBox', 'VirtualFDO', 'VirtualGPKG',\n");
+  str += wxT("'RasterLite2'\n\n");
+  strcpy(ver, spatialite_target_cpu());
+  str += wxT("Target CPU ") + wxString::FromUTF8(ver) + wxT("\n");
   dlg.SetDescription(str);
-  dlg.SetCopyright(wxT("by Alessandro Furieri - 2008/2013"));
+  dlg.SetCopyright(wxT("by Alessandro Furieri - 2008/2014"));
   dlg.SetWebSite(wxT("http://www.gaia-gis.it"));
   wxString license =
     wxT("This program is free software; you can redistribute it\n");
@@ -1308,27 +1426,54 @@ void MyFrame::OnMouseMove(wxMouseEvent & WXUNUSED(event))
 //
 // MOUSE motion - event handler
 //
-  UpdateStatusBar();
+  UpdateStatusBar(false);
 }
 
-void MyFrame::UpdateStatusBar()
+void MyFrame::UpdateStatusBar(bool changeIcon)
 {
 //
 // updating the status bar
 //
-  if (GetStatusBar() == NULL)
+  wxString msg;
+  if (StatusBar == NULL)
     return;
+  if (changeIcon == true)
+    {
+      // changing the current Icon 
+      if (IsConnected() == true)
+        {
+          if (ReadOnlyConnection == true)
+            StatusBar->SetReadOnlyIcon();
+          else
+            {
+              // showing the currently set SECURITY LEVEL
+              if (SecurityRelaxed == true)
+                StatusBar->SetSecurityRelaxedIcon();
+              else
+                StatusBar->SetSecurityStrongIcon();
+            }
+      } else
+        StatusBar->SetNotConnectedIcon();
+    }
   if (MemoryDatabase == true)
     {
-      GetStatusBar()->SetStatusText(wxT("Current SQLite DB: MEMORY-DB"), 0);
+      msg = wxT("Current SQLite DB: MEMORY-DB");
+      StatusBar->SetText(msg);
       QueryView->ShowControls();
   } else
     {
       if (SqlitePath.Len() < 1)
-        GetStatusBar()->SetStatusText(wxT("not connected"), 0);
-      else
-        GetStatusBar()->SetStatusText(wxT("Current SQLite DB: ") + SqlitePath,
-                                      0);
+        {
+          msg = wxT("not connected");
+          StatusBar->SetText(msg);
+      } else
+        {
+          if (ReadOnlyConnection)
+            msg = wxT("Current SQLite DB [READ-ONLY]: ") + SqlitePath;
+          else
+            msg = wxT("Current SQLite DB: ") + SqlitePath;
+          StatusBar->SetText(msg);
+        }
       if (SqlitePath.Len() < 1)
         {
           QueryView->HideControls();
@@ -1346,9 +1491,211 @@ void MyFrame::OnConnect(wxCommandEvent & WXUNUSED(event))
   int ret;
   wxString lastDir;
   wxString suffixList =
-    wxT("SpatiaLite DB (*.sqlite;*.atlas)|*.sqlite;*.atlas|");
+    wxT("SpatiaLite DB (*.sqlite;*.atlas;*.gpkg)|*.sqlite;*.atlas;*.gpkg|");
+  suffixList += wxT("SQLite DB (*.sqlite)|*.sqlite|");
+  suffixList += wxT("LibreAtlas DB (*.atlas)|*.atlas|");
+  suffixList += wxT("OGC GeoPackage (*.gpkg)|*.gpkg|");
+  suffixList += wxT("All files (*.*)|*.*");
+  wxFileDialog fileDialog(this, wxT("DB connection"),
+                          wxT(""), wxT("db.sqlite"), suffixList,
+                          wxFD_OPEN | wxFD_FILE_MUST_EXIST, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      SqlitePath = fileDialog.GetPath();
+      if (IsValidSqliteFile(SqlitePath) == false)
+        {
+          SqlitePath = wxT("");
+          return;
+        }
+      if (OpenDB(false) == false)
+        SqlitePath = wxT("");
+      else
+        {
+          wxFileName file(fileDialog.GetPath());
+          lastDir = file.GetPath();
+          SetLastDirectory(lastDir);
+          bool metadata = CheckMetadata();
+          wxMenuBar *menuBar = GetMenuBar();
+          menuBar->Enable(ID_Connect, false);
+          menuBar->Enable(ID_Connect_RO, false);
+          menuBar->Enable(ID_CreateNew, false);
+          menuBar->Enable(ID_Disconnect, true);
+          menuBar->Enable(ID_MemoryDbLoad, false);
+          menuBar->Enable(ID_MemoryDbNew, false);
+          if (MemoryDatabase == true)
+            {
+              menuBar->Enable(ID_MemoryDbSave, true);
+              menuBar->Enable(ID_MemoryDbClock, true);
+          } else
+            {
+              menuBar->Enable(ID_MemoryDbSave, false);
+              menuBar->Enable(ID_MemoryDbClock, false);
+            }
+          menuBar->Enable(ID_Vacuum, true);
+          menuBar->Enable(ID_SqlScript, true);
+          menuBar->Enable(ID_QueryViewComposer, HasViewsMetadata());
+          menuBar->Enable(ID_LoadShp, true);
+          menuBar->Enable(ID_VirtualShp, true);
+          menuBar->Enable(ID_LoadTxt, true);
+          menuBar->Enable(ID_VirtualTxt, true);
+          menuBar->Enable(ID_LoadDbf, true);
+          menuBar->Enable(ID_VirtualDbf, true);
+          menuBar->Enable(ID_LoadXL, true);
+          menuBar->Enable(ID_VirtualXL, true);
+          menuBar->Enable(ID_Network, true);
+          menuBar->Enable(ID_Exif, true);
+          menuBar->Enable(ID_LoadXml, true);
+          menuBar->Enable(ID_WFS, true);
+          menuBar->Enable(ID_DXF, true);
+          menuBar->Enable(ID_Srids, metadata);
+          menuBar->Enable(ID_Attach, true);
+          menuBar->Enable(ID_SqlLog, true);
+          menuBar->Enable(ID_DbStatus, true);
+          menuBar->Enable(ID_CheckGeom, true);
+          menuBar->Enable(ID_SaneGeom, true);
+          EnableSqlLog();
+          menuBar->Check(ID_SqlLog, SqlLogEnabled);
+          wxToolBar *toolBar = GetToolBar();
+          toolBar->EnableTool(ID_Connect, false);
+          toolBar->EnableTool(ID_Connect_RO, false);
+          toolBar->EnableTool(ID_CreateNew, false);
+          toolBar->EnableTool(ID_Disconnect, true);
+          toolBar->EnableTool(ID_MemoryDbLoad, false);
+          toolBar->EnableTool(ID_MemoryDbNew, false);
+          if (MemoryDatabase == true)
+            {
+              toolBar->EnableTool(ID_MemoryDbSave, true);
+              toolBar->EnableTool(ID_MemoryDbClock, true);
+          } else
+            {
+              toolBar->EnableTool(ID_MemoryDbSave, false);
+              toolBar->EnableTool(ID_MemoryDbClock, false);
+            }
+          toolBar->EnableTool(ID_Vacuum, true);
+          toolBar->EnableTool(ID_SqlScript, true);
+          toolBar->EnableTool(ID_QueryViewComposer, HasViewsMetadata());
+          toolBar->EnableTool(ID_LoadShp, true);
+          toolBar->EnableTool(ID_VirtualShp, true);
+          toolBar->EnableTool(ID_LoadTxt, true);
+          toolBar->EnableTool(ID_VirtualTxt, true);
+          toolBar->EnableTool(ID_LoadDbf, true);
+          toolBar->EnableTool(ID_VirtualDbf, true);
+          toolBar->EnableTool(ID_LoadXL, true);
+          toolBar->EnableTool(ID_VirtualXL, true);
+          toolBar->EnableTool(ID_Network, true);
+          toolBar->EnableTool(ID_Exif, true);
+          toolBar->EnableTool(ID_LoadXml, true);
+          toolBar->EnableTool(ID_WFS, true);
+          toolBar->EnableTool(ID_DXF, true);
+          toolBar->EnableTool(ID_Srids, metadata);
+          toolBar->EnableTool(ID_Attach, true);
+          toolBar->EnableTool(ID_SqlLog, true);
+          toolBar->EnableTool(ID_DbStatus, true);
+          toolBar->EnableTool(ID_CheckGeom, true);
+          toolBar->EnableTool(ID_SaneGeom, true);
+          toolBar->ToggleTool(ID_SqlLog, SqlLogEnabled);
+          UpdateStatusBar();
+        }
+    }
+  if (AutoFDOmsg.Len() > 0)
+    {
+      wxMessageBox(AutoFDOmsg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
+                   this);
+      AutoFDOmsg = wxT("");
+    }
+  if (AutoGPKGmsg.Len() > 0)
+    {
+      wxMessageBox(AutoGPKGmsg, wxT("spatialite_gui"),
+                   wxOK | wxICON_INFORMATION, this);
+      AutoGPKGmsg = wxT("");
+    }
+}
+
+void MyFrame::EnableAllTools(bool mode)
+{
+//
+// enabling - disabling all buttons while executing
+// a threaded sql query
+//
+  bool mode2;
+  bool mode3;
+  if (mode == true)
+    {
+      mode2 = HasViewsMetadata();
+      mode3 = CheckMetadata();
+  } else
+    {
+      mode2 = false;
+      mode3 = false;
+    }
+
+  wxMenuBar *menuBar = GetMenuBar();
+  menuBar->Enable(ID_Disconnect, mode);
+  menuBar->Enable(ID_Vacuum, mode);
+  menuBar->Enable(ID_SqlScript, mode);
+  menuBar->Enable(ID_QueryViewComposer, mode2);
+  menuBar->Enable(ID_LoadShp, mode);
+  menuBar->Enable(ID_VirtualShp, mode);
+  menuBar->Enable(ID_LoadTxt, mode);
+  menuBar->Enable(ID_VirtualTxt, mode);
+  menuBar->Enable(ID_LoadDbf, mode);
+  menuBar->Enable(ID_VirtualDbf, mode);
+  menuBar->Enable(ID_LoadXL, mode);
+  menuBar->Enable(ID_VirtualXL, mode);
+  menuBar->Enable(ID_Network, mode);
+  menuBar->Enable(ID_Exif, mode);
+  menuBar->Enable(ID_LoadXml, mode);
+  menuBar->Enable(ID_WFS, mode);
+  menuBar->Enable(ID_DXF, mode);
+  menuBar->Enable(ID_Srids, mode3);
+  menuBar->Enable(ID_Attach, mode);
+  menuBar->Enable(ID_SqlLog, mode);
+  menuBar->Enable(ID_DbStatus, mode);
+  menuBar->Enable(ID_CheckGeom, mode);
+  menuBar->Enable(ID_SaneGeom, mode);
+  wxToolBar *toolBar = GetToolBar();
+  toolBar->EnableTool(ID_Disconnect, mode);
+  toolBar->EnableTool(ID_Vacuum, mode);
+  toolBar->EnableTool(ID_SqlScript, mode);
+  toolBar->EnableTool(ID_QueryViewComposer, mode2);
+  toolBar->EnableTool(ID_LoadShp, mode);
+  toolBar->EnableTool(ID_VirtualShp, mode);
+  toolBar->EnableTool(ID_LoadTxt, mode);
+  toolBar->EnableTool(ID_VirtualTxt, mode);
+  toolBar->EnableTool(ID_LoadDbf, mode);
+  toolBar->EnableTool(ID_VirtualDbf, mode);
+  toolBar->EnableTool(ID_LoadXL, mode);
+  toolBar->EnableTool(ID_VirtualXL, mode);
+  toolBar->EnableTool(ID_Network, mode);
+  toolBar->EnableTool(ID_Exif, mode);
+  toolBar->EnableTool(ID_LoadXml, mode);
+  toolBar->EnableTool(ID_WFS, mode);
+  toolBar->EnableTool(ID_DXF, mode);
+  toolBar->EnableTool(ID_Srids, mode3);
+  toolBar->EnableTool(ID_Attach, mode);
+  toolBar->EnableTool(ID_SqlLog, mode);
+  toolBar->EnableTool(ID_DbStatus, mode);
+  toolBar->EnableTool(ID_CheckGeom, mode);
+  toolBar->EnableTool(ID_SaneGeom, mode);
+}
+
+void MyFrame::OnConnectReadOnly(wxCommandEvent & WXUNUSED(event))
+{
+//
+// connecting to an existent SQLite DB (Read Only)
+//
+  int ret;
+  wxString lastDir;
+  wxString suffixList =
+    wxT("SpatiaLite DB (*.sqlite;*.atlas;*.gpkg)|*.sqlite;*.atlas;*.gpkg|");
   suffixList += wxT("SQLite DB (*.sqlite)|*.sqlite|");
   suffixList += wxT("LibreAtlas DB (*.atlas)|*.atlas|");
+  suffixList += wxT("OGC GeoPackage (*.gpkg)|*.gpkg|");
   suffixList += wxT("All files (*.*)|*.*");
   wxFileDialog fileDialog(this, wxT("DB connection"),
                           wxT(""), wxT("db.sqlite"), suffixList,
@@ -1361,7 +1708,12 @@ void MyFrame::OnConnect(wxCommandEvent & WXUNUSED(event))
   if (ret == wxID_OK)
     {
       SqlitePath = fileDialog.GetPath();
-      if (OpenDB() == false)
+      if (IsValidSqliteFile(SqlitePath) == false)
+        {
+          SqlitePath = wxT("");
+          return;
+        }
+      if (OpenDB(true) == false)
         SqlitePath = wxT("");
       else
         {
@@ -1371,6 +1723,7 @@ void MyFrame::OnConnect(wxCommandEvent & WXUNUSED(event))
           bool metadata = CheckMetadata();
           wxMenuBar *menuBar = GetMenuBar();
           menuBar->Enable(ID_Connect, false);
+          menuBar->Enable(ID_Connect_RO, false);
           menuBar->Enable(ID_CreateNew, false);
           menuBar->Enable(ID_Disconnect, true);
           menuBar->Enable(ID_MemoryDbLoad, false);
@@ -1410,6 +1763,7 @@ void MyFrame::OnConnect(wxCommandEvent & WXUNUSED(event))
           menuBar->Check(ID_SqlLog, SqlLogEnabled);
           wxToolBar *toolBar = GetToolBar();
           toolBar->EnableTool(ID_Connect, false);
+          toolBar->EnableTool(ID_Connect_RO, false);
           toolBar->EnableTool(ID_CreateNew, false);
           toolBar->EnableTool(ID_Disconnect, true);
           toolBar->EnableTool(ID_MemoryDbLoad, false);
@@ -1455,6 +1809,12 @@ void MyFrame::OnConnect(wxCommandEvent & WXUNUSED(event))
                    this);
       AutoFDOmsg = wxT("");
     }
+  if (AutoGPKGmsg.Len() > 0)
+    {
+      wxMessageBox(AutoGPKGmsg, wxT("spatialite_gui"),
+                   wxOK | wxICON_INFORMATION, this);
+      AutoGPKGmsg = wxT("");
+    }
 }
 
 void MyFrame::OnDisconnect(wxCommandEvent & WXUNUSED(event))
@@ -1472,6 +1832,7 @@ void MyFrame::OnDisconnect(wxCommandEvent & WXUNUSED(event))
   ExternalSqlitePath = wxT("");
   wxMenuBar *menuBar = GetMenuBar();
   menuBar->Enable(ID_Connect, true);
+  menuBar->Enable(ID_Connect_RO, true);
   menuBar->Enable(ID_CreateNew, true);
   menuBar->Enable(ID_Disconnect, false);
   menuBar->Enable(ID_MemoryDbLoad, true);
@@ -1503,6 +1864,7 @@ void MyFrame::OnDisconnect(wxCommandEvent & WXUNUSED(event))
   SqlLogEnabled = false;
   wxToolBar *toolBar = GetToolBar();
   toolBar->EnableTool(ID_Connect, true);
+  toolBar->EnableTool(ID_Connect_RO, true);
   toolBar->EnableTool(ID_CreateNew, true);
   toolBar->EnableTool(ID_Disconnect, false);
   toolBar->EnableTool(ID_MemoryDbLoad, true);
@@ -1570,6 +1932,7 @@ void MyFrame::OnCreateNew(wxCommandEvent & WXUNUSED(event))
       SetLastDirectory(lastDir);
       wxMenuBar *menuBar = GetMenuBar();
       menuBar->Enable(ID_Connect, false);
+      menuBar->Enable(ID_Connect_RO, false);
       menuBar->Enable(ID_CreateNew, false);
       menuBar->Enable(ID_Disconnect, true);
       menuBar->Enable(ID_MemoryDbLoad, false);
@@ -1602,6 +1965,7 @@ void MyFrame::OnCreateNew(wxCommandEvent & WXUNUSED(event))
       menuBar->Check(ID_SqlLog, SqlLogEnabled);
       wxToolBar *toolBar = GetToolBar();
       toolBar->EnableTool(ID_Connect, false);
+      toolBar->EnableTool(ID_Connect_RO, false);
       toolBar->EnableTool(ID_CreateNew, false);
       toolBar->EnableTool(ID_Disconnect, true);
       toolBar->EnableTool(ID_MemoryDbLoad, false);
@@ -1671,6 +2035,8 @@ void MyFrame::OnMemoryDbLoad(wxCommandEvent & WXUNUSED(event))
       // opening the external DB
       ExternalSqlitePath = fileDialog.GetPath();
       strcpy(path, ExternalSqlitePath.ToUTF8());
+      // testing for an appropriate Security level
+      TestSecurityRelaxed(path);
       ret = sqlite3_open_v2(path, &extSqlite, SQLITE_OPEN_READWRITE, NULL);
       if (ret)
         {
@@ -1708,8 +2074,17 @@ void MyFrame::OnMemoryDbLoad(wxCommandEvent & WXUNUSED(event))
       ret = sqlite3_backup_finish(backup);
       sqlite3_close(extSqlite);
 // setting up the internal cache
-      InternalCache = spatialite_alloc_connection();
-      spatialite_init_ex(SqliteHandle, InternalCache, 0);
+      SpliteInternalCache = spatialite_alloc_connection();
+      spatialite_init_ex(SqliteHandle, SpliteInternalCache, 0);
+      rl2_init(SqliteHandle, RL2PrivateData, 0);
+// enabling LOAD_EXTENSION
+      ret = sqlite3_enable_load_extension(SqliteHandle, 1);
+      if (ret != SQLITE_OK)
+        {
+          wxMessageBox(wxT("Unable to enable LOAD_EXTENSION"),
+                       wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+          sqlite3_free(errMsg);
+        }
 // activating Foreign Key constraints
       ret =
         sqlite3_exec(SqliteHandle, "PRAGMA foreign_keys = 1", NULL, 0, &errMsg);
@@ -1719,13 +2094,19 @@ void MyFrame::OnMemoryDbLoad(wxCommandEvent & WXUNUSED(event))
                        wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
           goto stop;
         }
+// setting RL2 MaxThreads
+      char sqlmax[1024];
+      sprintf(sqlmax, "SELECT RL2_SetMaxThreads(%d)", RL2MaxThreads);
+      sqlite3_exec(SqliteHandle, sqlmax, NULL, 0, &errMsg);
       MemoryDatabase = true;
       AutoSaveInterval = 120;
       AutoFDOStart();
+      AutoGPKGStart();
       InitTableTree();
       bool metadata = CheckMetadata();
       wxMenuBar *menuBar = GetMenuBar();
       menuBar->Enable(ID_Connect, false);
+      menuBar->Enable(ID_Connect_RO, false);
       menuBar->Enable(ID_CreateNew, false);
       menuBar->Enable(ID_Disconnect, true);
       menuBar->Enable(ID_MemoryDbLoad, false);
@@ -1765,6 +2146,7 @@ void MyFrame::OnMemoryDbLoad(wxCommandEvent & WXUNUSED(event))
       menuBar->Check(ID_SqlLog, SqlLogEnabled);
       wxToolBar *toolBar = GetToolBar();
       toolBar->EnableTool(ID_Connect, false);
+      toolBar->EnableTool(ID_Connect_RO, false);
       toolBar->EnableTool(ID_CreateNew, false);
       toolBar->EnableTool(ID_Disconnect, true);
       toolBar->EnableTool(ID_MemoryDbLoad, false);
@@ -1829,6 +2211,12 @@ void MyFrame::OnMemoryDbLoad(wxCommandEvent & WXUNUSED(event))
                    this);
       AutoFDOmsg = wxT("");
     }
+  if (AutoGPKGmsg.Len() > 0)
+    {
+      wxMessageBox(AutoGPKGmsg, wxT("spatialite_gui"),
+                   wxOK | wxICON_INFORMATION, this);
+      AutoGPKGmsg = wxT("");
+    }
   return;
 stop:
   MemoryDatabase = false;
@@ -1836,13 +2224,13 @@ stop:
     sqlite3_close(SqliteHandle);
   if (extSqlite)
     sqlite3_close(extSqlite);
-  if (InternalCache)
-    spatialite_cleanup_ex(InternalCache);
+  if (SpliteInternalCache)
+    spatialite_cleanup_ex(SpliteInternalCache);
   wxString msg = wxT("MEMORY-DB wasn't loaded\n\n");
   msg += error;
   wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
   SqliteHandle = NULL;
-  InternalCache = NULL;
+  SpliteInternalCache = NULL;
 }
 
 void MyFrame::OnMemoryDbNew(wxCommandEvent & WXUNUSED(event))
@@ -1864,6 +2252,7 @@ void MyFrame::OnMemoryDbNew(wxCommandEvent & WXUNUSED(event))
   metadata = CheckMetadata();
   menuBar = GetMenuBar();
   menuBar->Enable(ID_Connect, false);
+  menuBar->Enable(ID_Connect_RO, false);
   menuBar->Enable(ID_CreateNew, false);
   menuBar->Enable(ID_Disconnect, true);
   menuBar->Enable(ID_MemoryDbLoad, false);
@@ -1896,6 +2285,7 @@ void MyFrame::OnMemoryDbNew(wxCommandEvent & WXUNUSED(event))
   menuBar->Check(ID_SqlLog, SqlLogEnabled);
   toolBar = GetToolBar();
   toolBar->EnableTool(ID_Connect, false);
+  toolBar->EnableTool(ID_Connect_RO, false);
   toolBar->EnableTool(ID_CreateNew, false);
   toolBar->EnableTool(ID_Disconnect, true);
   toolBar->EnableTool(ID_MemoryDbLoad, false);
@@ -2319,7 +2709,7 @@ void MyFrame::OnVacuum(wxCommandEvent & WXUNUSED(event))
       msg = wxT("Current DB was succesfully optimized");
       if (totalPages2 < totalPages)
         {
-          sprintf(dummy, "\n\n%d unused pages where reclaimed",
+          sprintf(dummy, "\n\n%d unused pages were reclaimed",
                   totalPages - totalPages2);
           msg += wxString::FromUTF8(dummy);
         }
@@ -2673,6 +3063,7 @@ void MyFrame::OnLoadShp(wxCommandEvent & WXUNUSED(event))
   wxString column = wxT("Geometry");
   wxString charset;
   int srid = 0;
+  int text_dates;
   int coerce2D;
   int compressed;
   int spatial_index;
@@ -2746,10 +3137,12 @@ void MyFrame::OnLoadShp(wxCommandEvent & WXUNUSED(event))
               strcpy(x_pkey, dlg.GetPKColumn().ToUTF8());
               pkey = x_pkey;
             }
+          text_dates = dlg.IsTextDates();
           ::wxBeginBusyCursor();
-          rt = load_shapefile_ex(SqliteHandle, x_path, x_table, x_charset, srid,
-                                 x_column, gtype, pkey, coerce2D, compressed, 0,
-                                 spatial_index, &rows, err_msg);
+          rt =
+            load_shapefile_ex2(SqliteHandle, x_path, x_table, x_charset, srid,
+                               x_column, gtype, pkey, coerce2D, compressed, 0,
+                               spatial_index, text_dates, &rows, err_msg);
           ::wxEndBusyCursor();
           if (rt)
             {
@@ -2781,6 +3174,7 @@ void MyFrame::OnVirtualShp(wxCommandEvent & WXUNUSED(event))
   wxString geometryType;
   char *errMsg = NULL;
   char xname[1024];
+  bool text_dates = false;
   sqlite3 *sqlite = GetSqlite();
   wxFileDialog fileDialog(this, wxT("VirtualShape"),
                           wxT(""),
@@ -2805,6 +3199,7 @@ void MyFrame::OnVirtualShp(wxCommandEvent & WXUNUSED(event))
           table = dlg.GetTable();
           srid = dlg.GetSrid();
           charset = dlg.GetCharset();
+          text_dates = dlg.IsTextDates();
       } else
         return;
       lastDir = file.GetPath();
@@ -2821,7 +3216,10 @@ void MyFrame::OnVirtualShp(wxCommandEvent & WXUNUSED(event))
       sql += charset;
       sprintf(dummy, "', %d", srid);
       sql += wxString::FromUTF8(dummy);
-      sql += wxT(")");
+      if (text_dates)
+        sql += wxT(", 1)");
+      else
+        sql += wxT(")");
       ret = sqlite3_exec(sqlite, sql.ToUTF8(), NULL, NULL, &errMsg);
       if (ret != SQLITE_OK)
         {
@@ -3030,6 +3428,7 @@ void MyFrame::OnLoadDbf(wxCommandEvent & WXUNUSED(event))
           char x_pkey[1024];
           char *pkey;
           char err_msg[1024];
+          int text_dates = 0;
           SetLastDirectory(lastDir);
           strcpy(x_path, path.ToUTF8());
           strcpy(x_table, dlg.GetTable().ToUTF8());
@@ -3041,9 +3440,11 @@ void MyFrame::OnLoadDbf(wxCommandEvent & WXUNUSED(event))
               strcpy(x_pkey, dlg.GetPKColumn().ToUTF8());
               pkey = x_pkey;
             }
+          text_dates = dlg.IsTextDates();
+
           rt =
-            load_dbf_ex(SqliteHandle, x_path, x_table, pkey, x_charset, 0,
-                        &rows, err_msg);
+            load_dbf_ex2(SqliteHandle, x_path, x_table, pkey, x_charset, 0,
+                         text_dates, &rows, err_msg);
           if (rt)
             wxMessageBox(wxT("load dbf OK:") +
                          wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
@@ -3069,6 +3470,7 @@ void MyFrame::OnVirtualDbf(wxCommandEvent & WXUNUSED(event))
   wxString lastDir;
   char *errMsg = NULL;
   char xname[1024];
+  bool text_dates = false;
   sqlite3 *sqlite = GetSqlite();
   wxString filelist = wxT("DBF files (*.dbf)|*.dbf|All files (*.*)|*.*");
   wxFileDialog fileDialog(this, wxT("VirtualDbf"),
@@ -3093,6 +3495,7 @@ void MyFrame::OnVirtualDbf(wxCommandEvent & WXUNUSED(event))
         {
           table = dlg.GetTable();
           charset = dlg.GetCharset();
+          text_dates = dlg.IsTextDates();
       } else
         return;
       lastDir = file.GetPath();
@@ -3105,7 +3508,10 @@ void MyFrame::OnVirtualDbf(wxCommandEvent & WXUNUSED(event))
       sql += path;
       sql += wxT("', '");
       sql += charset;
-      sql += wxT("')");
+      if (text_dates)
+        sql += wxT("', 1)");
+      else
+        sql += wxT("')");
       ret = sqlite3_exec(sqlite, sql.ToUTF8(), NULL, NULL, &errMsg);
       if (ret != SQLITE_OK)
         {
@@ -3269,6 +3675,7 @@ void MyFrame::OnNetwork(wxCommandEvent & WXUNUSED(event))
   wxString table;
   wxString from;
   wxString to;
+  bool isNoGeometry;
   wxString geom;
   wxString name;
   bool isGeomLength;
@@ -3278,6 +3685,8 @@ void MyFrame::OnNetwork(wxCommandEvent & WXUNUSED(event))
   wxString oneWayToFrom;
   wxString oneWayFromTo;
   bool aStarSupported;
+  wxString dataTableName;
+  wxString virtualTableName;
   dlg.Create(this);
   ret = dlg.ShowModal();
   if (ret == wxID_OK)
@@ -3285,6 +3694,7 @@ void MyFrame::OnNetwork(wxCommandEvent & WXUNUSED(event))
       table = dlg.GetTableName();
       from = dlg.GetFromColumn();
       to = dlg.GetToColumn();
+      isNoGeometry = dlg.IsNoGeometry();
       geom = dlg.GetGeomColumn();
       name = dlg.GetNameColumn();
       isGeomLength = dlg.IsGeomLength();
@@ -3294,9 +3704,11 @@ void MyFrame::OnNetwork(wxCommandEvent & WXUNUSED(event))
       oneWayToFrom = dlg.GetOneWayToFrom();
       oneWayFromTo = dlg.GetOneWayFromTo();
       aStarSupported = dlg.IsAStarSupported();
-      BuildNetwork(table, from, to, geom, name, isGeomLength, cost,
-                   isBidirectional, isOneWays, oneWayFromTo, oneWayToFrom,
-                   aStarSupported);
+      dataTableName = dlg.GetDataTable();
+      virtualTableName = dlg.GetVirtualTable();
+      BuildNetwork(table, from, to, isNoGeometry, geom, name, isGeomLength,
+                   cost, isBidirectional, isOneWays, oneWayFromTo, oneWayToFrom,
+                   aStarSupported, dataTableName, virtualTableName);
     }
 }
 
@@ -3398,7 +3810,7 @@ void MyFrame::OnImportWFS(wxCommandEvent & WXUNUSED(event))
 //
 #ifdef ENABLE_LIBXML2           /* only if LIBXML2 is enabled */
   WfsDialog dlg;
-  dlg.Create(this);
+  dlg.Create(this, WfsGetCapabilitiesURL, HttpProxy);
   dlg.ShowModal();
 
 #else
@@ -3479,70 +3891,987 @@ void MyFrame::OnImportDXF(wxCommandEvent & WXUNUSED(event))
     }
 }
 
-void MyFrame::OnImportExifPhotos(wxCommandEvent & WXUNUSED(event))
-{
-//
-// importing EXIF Photos
-//
-  ExifDialog dlg;
-  int ret;
-  wxString path;
-  bool isFolder;
-  bool isMetadata;
-  bool isGpsOnly;
-  wxString lastDir;
-  wxString dir_path;
-  wxString img_path;
-  wxString filelist = wxT("JPEG files (*.jpg;*.jpeg)|*.jpg;*.jpeg|");
-  filelist += wxT("All files (*.*)|*.*");
-  wxFileDialog fileDialog(this, wxT("EXIF File/Folder selection"),
-                          wxT(""),
-                          wxT(""),
-                          filelist,
-                          wxFD_OPEN | wxFD_FILE_MUST_EXIST,
-                          wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
-  lastDir = GetLastDirectory();
-  if (lastDir.Len() >= 1)
-    fileDialog.SetDirectory(lastDir);
-  ret = fileDialog.ShowModal();
-  if (ret == wxID_OK)
-    {
-      img_path = fileDialog.GetPath();
-      wxFileName file(img_path);
-      dir_path = file.GetPath();
-  } else
-    return;
-  dlg.Create(this, dir_path, img_path);
-  ret = dlg.ShowModal();
-  if (ret == wxID_OK)
-    {
-      SetLastDirectory(dir_path);
-      isFolder = dlg.IsFolder();
-      if (isFolder == true)
-        path = dlg.GetDirPath();
-      else
-        path = dlg.GetImgPath();
-      isMetadata = dlg.IsMetadata();
-      isGpsOnly = dlg.IsGpsOnly();
-      ImportExifPhotos(path, isFolder, isMetadata, isGpsOnly);
-    }
-}
-
-void MyFrame::OnSrids(wxCommandEvent & WXUNUSED(event))
+rl2PixelPtr MyFrame::DefaultNoData(unsigned char sample, unsigned char pixel,
+                                   unsigned char num_bands)
 {
-//
-// searching a SRID by name
-//
-  SearchSridDialog dlg;
-  int ret;
-  wxString string;
-  wxString sql;
-  dlg.Create(this);
-  ret = dlg.ShowModal();
-  if (ret == wxID_OK)
+/* creating a default NO-DATA value */
+  int nb;
+  rl2PixelPtr pxl = rl2_create_pixel(sample, pixel, num_bands);
+  if (pxl == NULL)
+    return NULL;
+  switch (pixel)
     {
-      sql = wxT("SELECT * FROM spatial_ref_sys\n");
-      if (dlg.IsSearchBySrid() == true)
+      case RL2_PIXEL_MONOCHROME:
+        rl2_set_pixel_sample_1bit(pxl, 0);
+        break;
+      case RL2_PIXEL_PALETTE:
+        switch (sample)
+          {
+            case RL2_SAMPLE_1_BIT:
+              rl2_set_pixel_sample_1bit(pxl, 0);
+              break;
+            case RL2_SAMPLE_2_BIT:
+              rl2_set_pixel_sample_2bit(pxl, 0);
+              break;
+            case RL2_SAMPLE_4_BIT:
+              rl2_set_pixel_sample_4bit(pxl, 0);
+              break;
+            case RL2_SAMPLE_UINT8:
+              rl2_set_pixel_sample_uint8(pxl, 0, 0);
+              break;
+          };
+        break;
+      case RL2_PIXEL_GRAYSCALE:
+        switch (sample)
+          {
+            case RL2_SAMPLE_1_BIT:
+              rl2_set_pixel_sample_1bit(pxl, 1);
+              break;
+            case RL2_SAMPLE_2_BIT:
+              rl2_set_pixel_sample_2bit(pxl, 3);
+              break;
+            case RL2_SAMPLE_4_BIT:
+              rl2_set_pixel_sample_4bit(pxl, 15);
+              break;
+            case RL2_SAMPLE_UINT8:
+              rl2_set_pixel_sample_uint8(pxl, 0, 255);
+              break;
+            case RL2_SAMPLE_UINT16:
+              rl2_set_pixel_sample_uint16(pxl, 0, 0);
+              break;
+          };
+        break;
+      case RL2_PIXEL_RGB:
+        switch (sample)
+          {
+            case RL2_SAMPLE_UINT8:
+              rl2_set_pixel_sample_uint8(pxl, 0, 255);
+              rl2_set_pixel_sample_uint8(pxl, 1, 255);
+              rl2_set_pixel_sample_uint8(pxl, 2, 255);
+              break;
+            case RL2_SAMPLE_UINT16:
+              rl2_set_pixel_sample_uint16(pxl, 0, 0);
+              rl2_set_pixel_sample_uint16(pxl, 1, 0);
+              rl2_set_pixel_sample_uint16(pxl, 2, 0);
+              break;
+          };
+        break;
+      case RL2_PIXEL_DATAGRID:
+        switch (sample)
+          {
+            case RL2_SAMPLE_INT8:
+              rl2_set_pixel_sample_int8(pxl, 0);
+              break;
+            case RL2_SAMPLE_UINT8:
+              rl2_set_pixel_sample_uint8(pxl, 0, 0);
+              break;
+            case RL2_SAMPLE_INT16:
+              rl2_set_pixel_sample_int16(pxl, 0);
+              break;
+            case RL2_SAMPLE_UINT16:
+              rl2_set_pixel_sample_uint16(pxl, 0, 0);
+              break;
+            case RL2_SAMPLE_INT32:
+              rl2_set_pixel_sample_int32(pxl, 0);
+              break;
+            case RL2_SAMPLE_UINT32:
+              rl2_set_pixel_sample_uint32(pxl, 0);
+              break;
+            case RL2_SAMPLE_FLOAT:
+              rl2_set_pixel_sample_float(pxl, 0.0);
+              break;
+            case RL2_SAMPLE_DOUBLE:
+              rl2_set_pixel_sample_double(pxl, 0.0);
+              break;
+          };
+        break;
+      case RL2_PIXEL_MULTIBAND:
+        switch (sample)
+          {
+            case RL2_SAMPLE_UINT8:
+              for (nb = 0; nb < num_bands; nb++)
+                rl2_set_pixel_sample_uint8(pxl, nb, 255);
+              break;
+            case RL2_SAMPLE_UINT16:
+              for (nb = 0; nb < num_bands; nb++)
+                rl2_set_pixel_sample_uint16(pxl, nb, 0);
+              break;
+          };
+        break;
+    };
+  return pxl;
+}
+
+char *MyFrame::GetNum(const char *start, const char *end)
+{
+/* extracting a token */
+  char *buf;
+  int len = end - start;
+  if (len <= 0)
+    return NULL;
+  buf = (char *) malloc(len + 1);
+  memcpy(buf, start, len);
+  *(buf + len) = '\0';
+  return buf;
+}
+
+rl2PixelPtr MyFrame::ParseNoData(wxString & NoData, int SampleType,
+                                 int PixelType, int NumBands)
+{
+//
+// parsing a NO-DATA string
+//
+  int band = 0;
+  char *num = NULL;
+  const char *p;
+  const char *start;
+  const char *end;
+  char int8_value = 0;
+  unsigned char uint8_value = 0;
+  short int16_value = 0;
+  unsigned short uint16_value = 0;
+  int int32_value = 0;
+  unsigned int uint32_value = 0;
+  float flt_value = 0.0;
+  double dbl_value = 0.0;
+  rl2PixelPtr pixel = NULL;
+  unsigned char num_bands = 0;
+  char buf[4192];
+  const char *in;
+
+  strcpy(buf, NoData.ToUTF8());
+  in = buf;
+
+  switch (PixelType)
+    {
+      case RL2_PIXEL_MONOCHROME:
+        num_bands = 1;
+        break;
+      case RL2_PIXEL_PALETTE:
+        num_bands = 1;
+        break;
+      case RL2_PIXEL_GRAYSCALE:
+        num_bands = 1;
+        break;
+      case RL2_PIXEL_RGB:
+        num_bands = 3;
+        break;
+      case RL2_PIXEL_DATAGRID:
+        num_bands = 1;
+        break;
+      case RL2_PIXEL_MULTIBAND:
+        num_bands = NumBands;
+        break;
+    };
+  if (num_bands != NumBands)
+    return NULL;
+  pixel = rl2_create_pixel(SampleType, PixelType, num_bands);
+  if (pixel == NULL)
+    return NULL;
+
+  start = in;
+  p = in;
+  while (1)
+    {
+      if (*p == ',' || *p == '\0')
+        {
+          end = p;
+          switch (SampleType)
+            {
+              case RL2_SAMPLE_1_BIT:
+                num = GetNum(start, end);
+                if (num == NULL)
+                  goto error;
+                uint8_value = atoi(num);
+                free(num);
+                num = NULL;
+                if (rl2_set_pixel_sample_1bit(pixel, int8_value) != RL2_OK)
+                  goto error;
+                break;
+              case RL2_SAMPLE_2_BIT:
+                num = GetNum(start, end);
+                if (num == NULL)
+                  goto error;
+                uint8_value = atoi(num);
+                free(num);
+                num = NULL;
+                if (rl2_set_pixel_sample_2bit(pixel, int8_value) != RL2_OK)
+                  goto error;
+                break;
+              case RL2_SAMPLE_4_BIT:
+                num = GetNum(start, end);
+                if (num == NULL)
+                  goto error;
+                uint8_value = atoi(num);
+                free(num);
+                num = NULL;
+                if (rl2_set_pixel_sample_4bit(pixel, int8_value) != RL2_OK)
+                  goto error;
+                break;
+              case RL2_SAMPLE_INT8:
+                num = GetNum(start, end);
+                if (num == NULL)
+                  goto error;
+                int8_value = atoi(num);
+                free(num);
+                num = NULL;
+                if (rl2_set_pixel_sample_int8(pixel, int8_value) != RL2_OK)
+                  goto error;
+                break;
+              case RL2_SAMPLE_UINT8:
+                num = GetNum(start, end);
+                if (num == NULL)
+                  goto error;
+                uint8_value = atoi(num);
+                free(num);
+                num = NULL;
+                if (rl2_set_pixel_sample_uint8(pixel, band, uint8_value)
+                    != RL2_OK)
+                  goto error;
+                break;
+              case RL2_SAMPLE_INT16:
+                num = GetNum(start, end);
+                if (num == NULL)
+                  goto error;
+                int16_value = atoi(num);
+                free(num);
+                num = NULL;
+                if (rl2_set_pixel_sample_int16(pixel, int16_value) != RL2_OK)
+                  goto error;
+                break;
+              case RL2_SAMPLE_UINT16:
+                num = GetNum(start, end);
+                if (num == NULL)
+                  goto error;
+                uint16_value = atoi(num);
+                free(num);
+                num = NULL;
+                if (rl2_set_pixel_sample_uint16
+                    (pixel, band, uint16_value) != RL2_OK)
+                  goto error;
+                break;
+              case RL2_SAMPLE_INT32:
+                num = GetNum(start, end);
+                if (num == NULL)
+                  goto error;
+                int32_value = atoi(num);
+                free(num);
+                num = NULL;
+                if (rl2_set_pixel_sample_int32(pixel, int32_value) != RL2_OK)
+                  goto error;
+                break;
+              case RL2_SAMPLE_UINT32:
+                num = GetNum(start, end);
+                if (num == NULL)
+                  goto error;
+                uint32_value = atoi(num);
+                free(num);
+                num = NULL;
+                if (rl2_set_pixel_sample_uint32(pixel, uint32_value) != RL2_OK)
+                  goto error;
+                break;
+              case RL2_SAMPLE_FLOAT:
+                num = GetNum(start, end);
+                if (num == NULL)
+                  goto error;
+                flt_value = atof(num);
+                free(num);
+                num = NULL;
+                if (rl2_set_pixel_sample_float(pixel, flt_value) != RL2_OK)
+                  goto error;
+                break;
+              case RL2_SAMPLE_DOUBLE:
+                num = GetNum(start, end);
+                if (num == NULL)
+                  goto error;
+                dbl_value = atof(num);
+                free(num);
+                num = NULL;
+                if (rl2_set_pixel_sample_double(pixel, dbl_value) != RL2_OK)
+                  goto error;
+                break;
+            };
+          if (*p == '\0')
+            break;
+          start = p + 1;
+          band++;
+        }
+      p++;
+    }
+  return pixel;
+
+error:
+  if (num != NULL)
+    free(num);
+  if (pixel != NULL)
+    rl2_destroy_pixel(pixel);
+  return NULL;
+}
+
+bool MyFrame::CreateRasterCoverage(wxString & CoverageName, wxString & Title,
+                                   wxString & Abstract, int SampleType,
+                                   int PixelType, int NumBands, int Compression,
+                                   int Quality, int TileWidth, int TileHeight,
+                                   bool NotGeoreferenced, int Srid,
+                                   double HorzResolution, double VertResolution,
+                                   wxString NoData, bool StrictResolution,
+                                   bool MixedResolutions, bool InputPaths,
+                                   bool MD5, bool Summary, int RedBand,
+                                   int GreenBand, int BlueBand, int NIRband,
+                                   bool AutoNDVI)
+{
+//
+// actual creation of a Raster Coverage 
+//
+  int ret;
+  const char *sql;
+  char *errMsg = NULL;
+  sqlite3_stmt *stmt = NULL;
+  char *err_msg = NULL;
+  int strict_resolution = 0;
+  int mixed_resolutions = 0;
+  int section_paths = 0;
+  int section_md5 = 0;
+  int section_summary = 0;
+  rl2PalettePtr palette = NULL;
+  rl2PixelPtr no_data = NULL;
+  bool retval = false;
+
+// starting a transaction 
+  ret = sqlite3_exec(SqliteHandle, "BEGIN", NULL, NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("BEGIN error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return false;
+    }
+// just in case, attempting to (re)create raster meta-tables
+  ret =
+    sqlite3_exec(SqliteHandle, "SELECT CreateRasterCoveragesTable()", NULL,
+                 NULL, &err_msg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("CreateRasterCoveragesTable() error: ") +
+                   wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      sqlite3_free(err_msg);
+      return false;
+    }
+  ret =
+    sqlite3_exec(SqliteHandle, "SELECT CreateStylingTables()", NULL, NULL,
+                 &err_msg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("CreateStylingTables() error: ") +
+                   wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      sqlite3_free(err_msg);
+      return false;
+    }
+
+  if (NoData.Len() == 0)
+    {
+      // creating a default NO-DATA value
+      no_data = DefaultNoData(SampleType, PixelType, NumBands);
+  } else
+    {
+      no_data = ParseNoData(NoData, SampleType, PixelType, NumBands);
+      if (no_data == NULL)
+        {
+          wxMessageBox(wxT("ERROR: invalid NO-DATA string"),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+          return false;
+        }
+    }
+  if (PixelType == RL2_PIXEL_PALETTE)
+    {
+      // creating a default PALETTE
+      palette = rl2_create_palette(1);
+      rl2_set_palette_color(palette, 0, 255, 255, 255);
+    }
+  if (NotGeoreferenced == true)
+    {
+      Srid = -1;
+      HorzResolution = 1.0;
+      VertResolution = 1.0;
+    }
+  if (StrictResolution)
+    strict_resolution = 1;
+  if (MixedResolutions)
+    mixed_resolutions = 1;
+  if (InputPaths)
+    section_paths = 1;
+  if (MD5)
+    section_md5 = 1;
+  if (Summary)
+    section_summary = 1;
+
+  if (rl2_create_dbms_coverage
+      (SqliteHandle, CoverageName.ToUTF8(), SampleType, PixelType, NumBands,
+       Compression, Quality, TileWidth, TileHeight, Srid, HorzResolution,
+       VertResolution, no_data, palette, strict_resolution, mixed_resolutions,
+       section_paths, section_md5, section_summary) != RL2_OK)
+    {
+      wxMessageBox(wxT("ERROR: unable to create Raster Coverage ") +
+                   CoverageName, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
+                   this);
+      return false;
+    }
+  if (PixelType == RL2_PIXEL_MULTIBAND)
+    {
+      if (RedBand >= 0 && GreenBand >= 0 && BlueBand >= 0 && NIRband >= 0)
+        {
+          // attempting to register the default Band Settings
+          rl2_set_dbms_coverage_default_bands(SqliteHandle,
+                                              CoverageName.ToUTF8(), RedBand,
+                                              GreenBand, BlueBand, NIRband);
+          if (AutoNDVI == true)
+            rl2_enable_dbms_coverage_auto_ndvi(SqliteHandle,
+                                               CoverageName.ToUTF8(), 1);
+        }
+    }
+// committing the still pending transaction 
+  ret = sqlite3_exec(SqliteHandle, "COMMIT", NULL, NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("COMMIT error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return false;
+    }
+// updating Title and Abstract
+  sql = "SELECT RL2_SetRasterCoverageInfos(?, ?, ?)";
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    {
+      const char *msg = sqlite3_errmsg(SqliteHandle);
+      wxMessageBox(wxT("ERROR - SetRasterCoverageInfos: ") +
+                   wxString::FromUTF8(msg), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      return false;
+    }
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 2, Title.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 3, Abstract.ToUTF8(), -1, SQLITE_TRANSIENT);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+    retval = true;
+  else
+    {
+      const char *msg = sqlite3_errmsg(SqliteHandle);
+      wxMessageBox(wxT("ERROR - SetRasterCoverageInfos: ") +
+                   wxString::FromUTF8(msg), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      retval = false;
+    }
+  sqlite3_finalize(stmt);
+  return retval;
+}
+
+bool MyFrame::DoGetRasterCoverageInfos(wxString & coverage, wxString & title,
+                                       wxString & abstract, wxString & sample,
+                                       wxString & pixel, wxString & compression,
+                                       int *srid)
+{
+//
+// attempting to retrieve basic Raster Coverage Infos
+//
+  const char *sql;
+  int ret;
+  int count = 0;
+  int err = 0;
+  sqlite3_stmt *stmt = NULL;
+
+  sql =
+    "SELECT title, abstract, sample_type, pixel_type, num_bands, compression, srid "
+    "FROM raster_coverages WHERE Lower(coverage_name) = Lower(?)";
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, coverage.ToUTF8(), coverage.Len(),
+                    SQLITE_TRANSIENT);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          count++;
+          const char *str;
+          if (sqlite3_column_type(stmt, 0) == SQLITE_TEXT)
+            {
+              str = (const char *) sqlite3_column_text(stmt, 0);
+              title = wxString::FromUTF8(str);
+          } else
+            title = wxT("*** Unknown ***");
+          if (sqlite3_column_type(stmt, 1) == SQLITE_TEXT)
+            {
+              str = (const char *) sqlite3_column_text(stmt, 1);
+              abstract = wxString::FromUTF8(str);
+          } else
+            abstract = wxT("*** Unknown ***");
+          if (sqlite3_column_type(stmt, 2) == SQLITE_TEXT)
+            {
+              str = (const char *) sqlite3_column_text(stmt, 2);
+              if (strcasecmp(str, "1 BIT") == 0)
+                sample = wxT("1-BIT");
+              else if (strcasecmp(str, "2 BIT") == 0)
+                sample = wxT("2-BIT");
+              else if (strcasecmp(str, "4 BIT") == 0)
+                sample = wxT("4-BIT");
+              else if (strcasecmp(str, "INT8") == 0)
+                sample = wxT("Signed Integer 8 bit");
+              else if (strcasecmp(str, "UINT8") == 0)
+                sample = wxT("Unsigned Integer 8 bit");
+              else if (strcasecmp(str, "INT16") == 0)
+                sample = wxT("Signed Integer 16 bit");
+              else if (strcasecmp(str, "UINT16") == 0)
+                sample = wxT("Unsigned Integer 16 bit");
+              else if (strcasecmp(str, "INT32") == 0)
+                sample = wxT("Signed Integer 32 bit");
+              else if (strcasecmp(str, "UINT32") == 0)
+                sample = wxT("Unsigned Integer 32 bit");
+              else if (strcasecmp(str, "FLOAT") == 0)
+                sample = wxT("Floating point single precision: 32 bit");
+              else if (strcasecmp(str, "DOUBLE") == 0)
+                sample = wxT("Floating point double precision: 64 bit");
+              else
+                {
+                  sample = wxT("*** Unknown ***");
+                  err = 1;
+                }
+          } else
+            {
+              sample = wxT("*** Unknown ***");
+              err = 1;
+            }
+          if (sqlite3_column_type(stmt, 3) == SQLITE_TEXT)
+            {
+              str = (const char *) sqlite3_column_text(stmt, 3);
+              if (strcasecmp(str, "MONOCHROME") == 0)
+                pixel = wxT("MonoChrome");
+              else if (strcasecmp(str, "PALETTE") == 0)
+                pixel = wxT("Palette-based");
+              else if (strcasecmp(str, "GRAYSCALE") == 0)
+                pixel = wxT("GrayScale (black&white)");
+              else if (strcasecmp(str, "RGB") == 0)
+                pixel = wxT("RGB (TrueColor)");
+              else if (strcasecmp(str, "MULTIBAND") == 0)
+                {
+                  pixel = wxT("MultiBand");
+                  if (sqlite3_column_type(stmt, 4) == SQLITE_INTEGER)
+                    {
+                      char dummy[128];
+                      sprintf(dummy, ": %d bands", sqlite3_column_int(stmt, 4));
+                      pixel += wxString::FromUTF8(dummy);
+                  } else
+                    {
+                      pixel += wxT(": unknown bands");
+                      err = 1;
+                    }
+              } else if (strcasecmp(str, "DATAGRID") == 0)
+                pixel = wxT("Data Grid");
+              else
+                {
+                  pixel = wxT("*** Unknown ***");
+                  err = 1;
+                }
+          } else
+            {
+              pixel = wxT("*** Unknown ***");
+              err = 1;
+            }
+          if (sqlite3_column_type(stmt, 5) == SQLITE_TEXT)
+            {
+              str = (const char *) sqlite3_column_text(stmt, 5);
+              if (strcasecmp(str, "NONE") == 0)
+                compression = wxT("None, not compressed");
+              else if (strcasecmp(str, "DEFLATE") == 0)
+                compression =
+                  wxT("Deflate (ZIP) with Delta-encoding: lossless");
+              else if (strcasecmp(str, "DEFLATE_NO") == 0)
+                compression = wxT("Deflate (ZIP), no Delta-encoding: lossless");
+              else if (strcasecmp(str, "LZMA") == 0)
+                compression = wxT("LZMA (7-Zip) with Delta-encoding: lossless");
+              else if (strcasecmp(str, "LZMA_NO") == 0)
+                compression = wxT("LZMA (7-Zip), no Delta-encoding: lossless");
+              else if (strcasecmp(str, "PNG") == 0)
+                compression = wxT("PNG: lossless");
+              else if (strcasecmp(str, "JPEG") == 0)
+                compression = wxT("JPEG: lossy");
+              else if (strcasecmp(str, "LOSSY_WEBP") == 0)
+                compression = wxT("WebP: lossy mode");
+              else if (strcasecmp(str, "LOSSLESS_WEBP") == 0)
+                compression = wxT("WebP: lossless mode");
+              else if (strcasecmp(str, "CCITTFAX4") == 0)
+                compression = wxT("Fax Group 4: lossless");
+              else if (strcasecmp(str, "CHARLS") == 0)
+                compression = wxT("CharLS [JPEG-LS]: lossless");
+              else if (strcasecmp(str, "LOSSY_JP2") == 0)
+                compression = wxT("JPEG2000: lossy mode");
+              else if (strcasecmp(str, "LOSSLESS_JP2") == 0)
+                compression = wxT("JPEG2000: lossless mode");
+              else
+                {
+                  compression = wxT("*** Unknown ***");
+                  err = 1;
+                }
+          } else
+            {
+              compression = wxT("*** Unknown ***");
+              err = 1;
+            }
+          if (sqlite3_column_type(stmt, 6) == SQLITE_INTEGER)
+            *srid = sqlite3_column_int(stmt, 6);
+          else
+            {
+              *srid = -1;
+              err = 1;
+            }
+      } else
+        break;
+    }
+  sqlite3_finalize(stmt);
+  if (count != 1 || err)
+    {
+      wxMessageBox(wxT("Unable to retrieve a valid Raster Coverage named: ") +
+                   coverage, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      return false;
+    }
+  return true;
+}
+
+bool MyFrame::DoGetVectorCoverageInfos(wxString & coverage, wxString & title,
+                                       wxString & abstract, wxString & type,
+                                       int *srid)
+{
+//
+// attempting to retrieve basic Vector Coverage Infos
+//
+  const char *sql;
+  int ret;
+  int count = 0;
+  int err = 0;
+  sqlite3_stmt *stmt = NULL;
+
+  sql =
+    "SELECT c.title, c.abstract, g.geometry_type, g.srid "
+    "FROM vector_coverages AS c JOIN geometry_columns AS g ON ("
+    "Lower(c.f_table_name) = Lower(g.f_table_name) AND "
+    "Lower(c.f_geometry_column) = Lower(g.f_geometry_column)) "
+    "WHERE Lower(c.coverage_name) = Lower(?)";
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, coverage.ToUTF8(), coverage.Len(),
+                    SQLITE_TRANSIENT);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          count++;
+          const char *str;
+          if (sqlite3_column_type(stmt, 0) == SQLITE_TEXT)
+            {
+              str = (const char *) sqlite3_column_text(stmt, 0);
+              title = wxString::FromUTF8(str);
+          } else
+            title = wxT("*** Unknown ***");
+          if (sqlite3_column_type(stmt, 1) == SQLITE_TEXT)
+            {
+              str = (const char *) sqlite3_column_text(stmt, 1);
+              abstract = wxString::FromUTF8(str);
+          } else
+            abstract = wxT("*** Unknown ***");
+          if (sqlite3_column_type(stmt, 2) == SQLITE_INTEGER)
+            {
+              int gtype = sqlite3_column_int(stmt, 2);
+              switch (gtype)
+                {
+                  case 0:
+                  case 1000:
+                  case 2000:
+                  case 3000:
+                    type = wxT("GEOMETRY");
+                    break;
+                  case 1:
+                  case 1001:
+                  case 2001:
+                  case 3001:
+                    type = wxT("POINT");
+                    break;
+                  case 2:
+                  case 1002:
+                  case 2002:
+                  case 3002:
+                    type = wxT("LINESTRING");
+                    break;
+                  case 3:
+                  case 1003:
+                  case 2003:
+                  case 3003:
+                    type = wxT("POLYGON");
+                    break;
+                  case 4:
+                  case 1004:
+                  case 2004:
+                  case 3004:
+                    type = wxT("MULTIPOINT");
+                    break;
+                  case 5:
+                  case 1005:
+                  case 2005:
+                  case 3005:
+                    type = wxT("MULTILINESTRING");
+                    break;
+                  case 6:
+                  case 1006:
+                  case 2006:
+                  case 3006:
+                    type = wxT("MULTIPOLYGON");
+                    break;
+                  case 7:
+                  case 1007:
+                  case 2007:
+                  case 3007:
+                    type = wxT("GEOMETRYCOLLECTION");
+                    break;
+                  default:
+                    type = wxT("***  UNKNOWN  ***");
+                    break;
+                };
+              switch (gtype)
+                {
+                  case 0:
+                  case 1:
+                  case 2:
+                  case 3:
+                  case 4:
+                  case 5:
+                  case 6:
+                  case 7:
+                    type += wxT(" XY");
+                    break;
+                  case 1000:
+                  case 1001:
+                  case 1002:
+                  case 1003:
+                  case 1004:
+                  case 1005:
+                  case 1006:
+                  case 1007:
+                    type += wxT(" XYZ");
+                    break;
+                  case 2000:
+                  case 2001:
+                  case 2002:
+                  case 2003:
+                  case 2004:
+                  case 2005:
+                  case 2006:
+                  case 2007:
+                    type += wxT(" XYM");
+                    break;
+                  case 3000:
+                  case 3001:
+                  case 3002:
+                  case 3003:
+                  case 3004:
+                  case 3005:
+                  case 3006:
+                  case 3007:
+                    type += wxT(" XYZM");
+                    break;
+                };
+          } else
+            {
+              type = wxT("***  UNKNOWN  ***");
+              err = 1;
+            }
+          if (sqlite3_column_type(stmt, 3) == SQLITE_INTEGER)
+            *srid = sqlite3_column_int(stmt, 3);
+          else
+            {
+              *srid = -1;
+              err = 1;
+            }
+      } else
+        break;
+    }
+  sqlite3_finalize(stmt);
+  if (count != 1 || err)
+    {
+      wxMessageBox(wxT("Unable to retrieve a valid Vector Coverage named: ") +
+                   coverage, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      return false;
+    }
+  return true;
+}
+
+bool MyFrame::DoImportRaster(sqlite3_stmt * stmt, wxString & coverage,
+                             wxString & path, int forced_srid,
+                             bool with_worldfile, bool pyramidize)
+{
+//
+// attempting to import a single Raster file into a Raster Coverage
+//
+  int ret;
+  bool retval = false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, coverage.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 2, path.ToUTF8(), -1, SQLITE_TRANSIENT);
+  if (with_worldfile == false)
+    sqlite3_bind_int(stmt, 3, 0);
+  else
+    sqlite3_bind_int(stmt, 3, 1);
+  sqlite3_bind_int(stmt, 4, forced_srid);
+  if (pyramidize == false)
+    sqlite3_bind_int(stmt, 5, 0);
+  else
+    sqlite3_bind_int(stmt, 5, 1);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          int status = sqlite3_column_int(stmt, 0);
+          if (status <= 0)
+            {
+              wxMessageBox(wxT("RL2_LoadRaster: \"") + path + wxT("\" error"),
+                           wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+          } else
+            retval = true;
+      } else
+        {
+          wxMessageBox(wxT("RL2_LoadRaster: sqlite3_step() error"),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+        }
+    }
+  return retval;
+}
+
+void MyFrame::DoCreateStylingTables()
+{
+//
+// attempting to create (just in case) the Styling Tables
+//
+  int ret;
+  const char *sql;
+  char *errMsg = NULL;
+
+// starting a transaction 
+  ret = sqlite3_exec(SqliteHandle, "BEGIN", NULL, NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("BEGIN error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return;
+    }
+// just in case, attempting to (re)create raster meta-tables
+  ret =
+    sqlite3_exec(SqliteHandle, "SELECT CreateStylingTables()", NULL,
+                 NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("CreateStylingTables() error: ") +
+                   wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return;
+    }
+// committing the still pending transaction 
+  ret = sqlite3_exec(SqliteHandle, "COMMIT", NULL, NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("COMMIT error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return;
+    }
+}
+
+void MyFrame::OnImportExifPhotos(wxCommandEvent & WXUNUSED(event))
+{
+//
+// importing EXIF Photos
+//
+  ExifDialog dlg;
+  int ret;
+  wxString path;
+  bool isFolder;
+  bool isMetadata;
+  bool isGpsOnly;
+  wxString lastDir;
+  wxString dir_path;
+  wxString img_path;
+  wxString filelist = wxT("JPEG files (*.jpg;*.jpeg)|*.jpg;*.jpeg|");
+  filelist += wxT("All files (*.*)|*.*");
+  wxFileDialog fileDialog(this, wxT("EXIF File/Folder selection"),
+                          wxT(""),
+                          wxT(""),
+                          filelist,
+                          wxFD_OPEN | wxFD_FILE_MUST_EXIST,
+                          wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
+  lastDir = GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      img_path = fileDialog.GetPath();
+      wxFileName file(img_path);
+      dir_path = file.GetPath();
+  } else
+    return;
+  dlg.Create(this, dir_path, img_path);
+  ret = dlg.ShowModal();
+  if (ret == wxID_OK)
+    {
+      SetLastDirectory(dir_path);
+      isFolder = dlg.IsFolder();
+      if (isFolder == true)
+        path = dlg.GetDirPath();
+      else
+        path = dlg.GetImgPath();
+      isMetadata = dlg.IsMetadata();
+      isGpsOnly = dlg.IsGpsOnly();
+      ImportExifPhotos(path, isFolder, isMetadata, isGpsOnly);
+    }
+}
+
+void MyFrame::OnSrids(wxCommandEvent & WXUNUSED(event))
+{
+//
+// searching a SRID by name
+//
+  SearchSridDialog dlg;
+  int ret;
+  wxString string;
+  wxString sql;
+  dlg.Create(this);
+  ret = dlg.ShowModal();
+  if (ret == wxID_OK)
+    {
+      sql = wxT("SELECT * FROM spatial_ref_sys\n");
+      if (dlg.IsSearchBySrid() == true)
         {
           // searching by SRID
           char txt[128];
@@ -3622,16 +4951,27 @@ void MyFrame::Rollback()
   sqlite3_exec(SqliteHandle, "ROLLBACK", NULL, NULL, NULL);
 }
 
-bool MyFrame::OpenDB()
+bool MyFrame::OpenDB(bool read_only)
 {
 //
-// establishing a physical connetion to some DB SQLite
+// establishing a physical connection to some DB SQLite
 //
   int ret;
   char *errMsg = NULL;
-  ret =
-    sqlite3_open_v2(SqlitePath.ToUTF8(), &SqliteHandle, SQLITE_OPEN_READWRITE,
-                    NULL);
+  int mode = SQLITE_OPEN_READWRITE;
+  ReadOnlyConnection = false;
+  if (read_only)
+    {
+      mode = SQLITE_OPEN_READONLY;
+      ReadOnlyConnection = true;
+  } else
+    {
+      // testing for an appropriate Security level
+      char path[1024];
+      strcpy(path, SqlitePath.ToUTF8());
+      TestSecurityRelaxed(path);
+    }
+  ret = sqlite3_open_v2(SqlitePath.ToUTF8(), &SqliteHandle, mode, NULL);
   if (ret)
     {
       // an error occurred
@@ -3642,14 +4982,15 @@ bool MyFrame::OpenDB()
                    wxT("\n") + SqlitePath, wxT("spatialite_gui"),
                    wxOK | wxICON_ERROR, this);
       SqliteHandle = NULL;
-      InternalCache = NULL;
+      SpliteInternalCache = NULL;
       ClearTableTree();
       MemoryDatabase = false;
       return false;
     }
 // setting up the internal cache
-  InternalCache = spatialite_alloc_connection();
-  spatialite_init_ex(SqliteHandle, InternalCache, 0);
+  SpliteInternalCache = spatialite_alloc_connection();
+  spatialite_init_ex(SqliteHandle, SpliteInternalCache, 0);
+  rl2_init(SqliteHandle, RL2PrivateData, 0);
 // enabling LOAD_EXTENSION
   ret = sqlite3_enable_load_extension(SqliteHandle, 1);
   if (ret != SQLITE_OK)
@@ -3666,7 +5007,12 @@ bool MyFrame::OpenDB()
                    wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
       sqlite3_free(errMsg);
     }
+// setting RL2 MaxThreads
+  char sqlmax[1024];
+  sprintf(sqlmax, "SELECT RL2_SetMaxThreads(%d)", RL2MaxThreads);
+  sqlite3_exec(SqliteHandle, sqlmax, NULL, 0, &errMsg);
   AutoFDOStart();
+  AutoGPKGStart();
   InitTableTree();
   LoadHistory();
   return true;
@@ -3733,6 +5079,89 @@ void MyFrame::LastDitchMemoryDbSave()
     }
 }
 
+int MyFrame::GetDecimalPrecision()
+{
+//
+// querying the currently set decimal precision
+//
+  int precision = -1;
+  const char *sql = "SELECT GetDecimalPrecision()";
+  int ret;
+  sqlite3_stmt *stmt = NULL;
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return precision;
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            precision = sqlite3_column_int(stmt, 0);
+      } else
+        break;
+    }
+  sqlite3_finalize(stmt);
+  return precision;
+}
+
+void MyFrame::DoUpdateRL2MaxThreads()
+{
+//
+// updating RL2MaxThreads
+//
+  const char *sql = "SELECT RL2_GetMaxThreads()";
+  int ret;
+  sqlite3_stmt *stmt = NULL;
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  RL2MaxThreads = 1;
+  if (ret != SQLITE_OK)
+    return;
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            RL2MaxThreads = sqlite3_column_int(stmt, 0);
+      } else
+        break;
+    }
+  sqlite3_finalize(stmt);
+}
+
+int MyFrame::GetRL2MaxThreads()
+{
+//
+// retrieving RL2MaxThreads
+//
+  const char *sql = "SELECT RL2_GetMaxThreads()";
+  int ret;
+  sqlite3_stmt *stmt = NULL;
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  int maxThreads = 1;
+  if (ret != SQLITE_OK)
+    return maxThreads;
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            maxThreads = sqlite3_column_int(stmt, 0);
+      } else
+        break;
+    }
+  sqlite3_finalize(stmt);
+  return maxThreads;
+}
+
 void MyFrame::CloseDB()
 {
 //
@@ -3741,16 +5170,23 @@ void MyFrame::CloseDB()
   if (!SqliteHandle)
     return;
   AutoFDOStop();
+  AutoGPKGStop();
   if (AutoFDOmsg.Len() > 0)
     wxMessageBox(AutoFDOmsg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
                  this);
+  if (AutoGPKGmsg.Len() > 0)
+    wxMessageBox(AutoGPKGmsg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
+                 this);
   LastDitchMemoryDbSave();
+  DoUpdateRL2MaxThreads();
   sqlite3_close(SqliteHandle);
   SqliteHandle = NULL;
-  spatialite_cleanup_ex(InternalCache);
-  InternalCache = NULL;
+  spatialite_cleanup_ex(SpliteInternalCache);
+  SpliteInternalCache = NULL;
   SqlitePath = wxT("");
+  ReadOnlyConnection = false;
   MemoryDatabase = false;
+  ResetSecurity();
   ClearTableTree();
 }
 
@@ -3760,6 +5196,7 @@ bool MyFrame::CreateDB()
   int ret;
   char path[1024];
   char *errMsg = NULL;
+  ReadOnlyConnection = false;
   if (MemoryDatabase == true)
     strcpy(path, ":memory:");
   else
@@ -3767,6 +5204,7 @@ bool MyFrame::CreateDB()
       strcpy(path, SqlitePath.ToUTF8());
       unlink(path);
     }
+  SetSecurityRelaxed();
   ret =
     sqlite3_open_v2(path, &SqliteHandle,
                     SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
@@ -3780,14 +5218,23 @@ bool MyFrame::CreateDB()
                    SqlitePath, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
                    this);
       SqliteHandle = NULL;
-      InternalCache = NULL;
+      SpliteInternalCache = NULL;
       ClearTableTree();
       MemoryDatabase = false;
       return false;
     }
 // setting up the internal cache
-  InternalCache = spatialite_alloc_connection();
-  spatialite_init_ex(SqliteHandle, InternalCache, 0);
+  SpliteInternalCache = spatialite_alloc_connection();
+  spatialite_init_ex(SqliteHandle, SpliteInternalCache, 0);
+  rl2_init(SqliteHandle, RL2PrivateData, 0);
+// enabling LOAD_EXTENSION
+  ret = sqlite3_enable_load_extension(SqliteHandle, 1);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("Unable to enable LOAD_EXTENSION"),
+                   wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+      sqlite3_free(errMsg);
+    }
 // activating Foreign Key constraints
   ret = sqlite3_exec(SqliteHandle, "PRAGMA foreign_keys = 1", NULL, 0, &errMsg);
   if (ret != SQLITE_OK)
@@ -3800,8 +5247,13 @@ bool MyFrame::CreateDB()
       MemoryDatabase = false;
       return false;
     }
+// setting RL2 MaxThreads
+  char sqlmax[1024];
+  sprintf(sqlmax, "SELECT RL2_SetMaxThreads(%d)", RL2MaxThreads);
+  sqlite3_exec(SqliteHandle, sqlmax, NULL, 0, &errMsg);
   InitializeSpatialMetadata();
   AutoFDOStart();
+  AutoGPKGStart();
   InitTableTree();
   return true;
 }
@@ -3967,6 +5419,7 @@ bool MyFrame::IsSpatialIndex(wxString & tableName)
   char dummy[2048];
   wxString tblName;
   wxString sql;
+  bool status = false;
 // fetching any defined Spatial Index
   sql =
     wxT
@@ -3986,23 +5439,36 @@ bool MyFrame::IsSpatialIndex(wxString & tableName)
           sprintf(dummy, "idx_%s_%s", name, geom);
           tblName = wxString::FromUTF8(dummy);
           if (tableName.CmpNoCase(tblName) == 0)
-            return true;
+            {
+              status = true;
+              goto end;
+            }
           sprintf(dummy, "idx_%s_%s_node", name, geom);
           tblName = wxString::FromUTF8(dummy);
           if (tableName.CmpNoCase(tblName) == 0)
-            return true;
+            {
+              status = true;
+              goto end;
+            }
           sprintf(dummy, "idx_%s_%s_parent", name, geom);
           tblName = wxString::FromUTF8(dummy);
           if (tableName.CmpNoCase(tblName) == 0)
-            return true;
+            {
+              status = true;
+              goto end;
+            }
           sprintf(dummy, "idx_%s_%s_rowid", name, geom);
           tblName = wxString::FromUTF8(dummy);
           if (tableName.CmpNoCase(tblName) == 0)
-            return true;
+            {
+              status = true;
+              goto end;
+            }
         }
     }
+end:
   sqlite3_free_table(results);
-  return false;
+  return status;
 }
 
 bool MyFrame::IsSpatialIndex(wxString & dbAlias, wxString & tableName)
@@ -4036,23 +5502,27 @@ bool MyFrame::IsSpatialIndex(wxString & dbAlias, wxString & tableName)
           sprintf(dummy, "idx_%s_%s", name, geom);
           tblName = wxString::FromUTF8(dummy);
           if (tableName.CmpNoCase(tblName) == 0)
-            return true;
+            goto exit_ok;
           sprintf(dummy, "idx_%s_%s_node", name, geom);
           tblName = wxString::FromUTF8(dummy);
           if (tableName.CmpNoCase(tblName) == 0)
-            return true;
+            goto exit_ok;
           sprintf(dummy, "idx_%s_%s_parent", name, geom);
           tblName = wxString::FromUTF8(dummy);
           if (tableName.CmpNoCase(tblName) == 0)
-            return true;
+            goto exit_ok;
           sprintf(dummy, "idx_%s_%s_rowid", name, geom);
           tblName = wxString::FromUTF8(dummy);
           if (tableName.CmpNoCase(tblName) == 0)
-            return true;
+            goto exit_ok;
         }
     }
   sqlite3_free_table(results);
   return false;
+
+exit_ok:
+  sqlite3_free_table(results);
+  return true;
 }
 
 void MyFrame::ElementaryGeoms(wxString & inTable, wxString & geometry,
@@ -5089,6 +6559,57 @@ gaiaGeomCollPtr MyFrame::GeomFromPolygon(gaiaPolygonPtr pg, int srid)
   return g;
 }
 
+bool MyFrame::GetTilePreview(wxString & currentTileData, int currentTileId,
+                             unsigned char **blob, int *blobSize)
+{
+// creating a TilePreview
+  bool success = false;
+  int ret;
+  sqlite3_stmt *stmt;
+  if (currentTileData.Len() == 0)
+    return false;
+  char table[1024];
+  strcpy(table, currentTileData.ToUTF8());
+  char *sql =
+    sqlite3_mprintf("SELECT RL2_GetTileImage(%Q, %d)", table, currentTileId);
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    return false;
+  while (1)
+    {
+      //
+      // fetching the result set rows 
+      //
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;                  // end of result set
+      if (ret == SQLITE_ROW)
+        {
+          //
+          // fetching a row
+          //
+          if (sqlite3_column_type(stmt, 0) == SQLITE_BLOB)
+            {
+              const unsigned char *p_blob =
+                (const unsigned char *) sqlite3_column_blob(stmt, 0);
+              *blobSize = sqlite3_column_bytes(stmt, 0);
+              *blob = new unsigned char[*blobSize];
+              memcpy(*blob, p_blob, *blobSize);
+              success = true;
+            }
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (success == false)
+    return false;
+  return true;
+}
+
 void MyFrame::InitTableTree()
 {
 // loads the table TREE list
@@ -5102,6 +6623,8 @@ void MyFrame::InitTableTree()
   char *type;
   wxString tblName;
   wxString sql;
+  TableViewList *list;
+  TableViewItem *ptv;
   bool virtualTable = false;
   TableTree->Show(false);
   if (MemoryDatabase == true)
@@ -5113,13 +6636,12 @@ void MyFrame::InitTableTree()
   TableTree->FlushAll();
   if (ExistsTopologyMaster())
     {
-      //
+      // fetching topologies
       wxString column_list;
       GetTopologyColumns(&column_list);
-      // fetching topologies
       sql = wxT("SELECT ");
       sql += column_list;
-      sql += wxT(" FROM topology_master");
+      sql += wxT(" FROM main.topology_master");
       int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
                                   &rows, &columns, &errMsg);
       if (ret != SQLITE_OK)
@@ -5172,10 +6694,70 @@ void MyFrame::InitTableTree()
         }
       sqlite3_free_table(results);
     }
+  if (ExistsRasterCoverages())
+    {
+      // fetching Raster Coverages
+      sql = wxT("SELECT coverage_name, srid FROM main.raster_coverages");
+      int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
+                                  &rows, &columns, &errMsg);
+      if (ret != SQLITE_OK)
+        {
+          wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+          sqlite3_free(errMsg);
+          return;
+        }
+      if (rows < 1)
+        ;
+      else
+        {
+          for (i = 1; i <= rows; i++)
+            {
+              // adding some Raster Coverage
+              const char *name = results[(i * columns) + 0];
+              int srid = atoi(results[(i * columns) + 1]);
+              RasterCoverageSet coverage(name, srid);
+              TableTree->AddRasterCoverage(&coverage);
+            }
+        }
+      sqlite3_free_table(results);
+    }
+  if (ExistsVectorCoverages())
+    {
+      // fetching Vector Coverages
+      sql =
+        wxT("SELECT c.coverage_name, g.srid FROM main.vector_coverages AS c ");
+      sql += wxT("JOIN geometry_columns AS g ON (");
+      sql += wxT("Lower(c.f_table_name) = Lower(g.f_table_name) AND ");
+      sql += wxT("Lower(c.f_geometry_column) = Lower(g.f_geometry_column))");
+      int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
+                                  &rows, &columns, &errMsg);
+      if (ret != SQLITE_OK)
+        {
+          wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+          sqlite3_free(errMsg);
+          return;
+        }
+      if (rows < 1)
+        ;
+      else
+        {
+          for (i = 1; i <= rows; i++)
+            {
+              // adding some Vector Coverage
+              const char *name = results[(i * columns) + 0];
+              int srid = atoi(results[(i * columns) + 1]);
+              VectorCoverageSet coverage(name, srid);
+              TableTree->AddVectorCoverage(&coverage);
+            }
+        }
+      sqlite3_free_table(results);
+    }
 // fetching persistent tables and views
   sql =
     wxT
-    ("SELECT name, sql, type FROM sqlite_master WHERE (type = 'table' OR type = 'view') ORDER BY name");
+    ("SELECT name, sql, type FROM main.sqlite_master WHERE (type = 'table' OR type = 'view') ORDER BY name");
   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
                               &rows, &columns, &errMsg);
   if (ret != SQLITE_OK)
@@ -5185,6 +6767,7 @@ void MyFrame::InitTableTree()
       sqlite3_free(errMsg);
       return;
     }
+  list = new TableViewList();
   if (rows < 1)
     ;
   else
@@ -5200,12 +6783,27 @@ void MyFrame::InitTableTree()
             virtualTable = false;
           tblName = wxString::FromUTF8(name);
           if (strcmp(type, "view") == 0)
-            TableTree->AddView(tblName, false);
+            list->Add(tblName, true, false);
           else
-            TableTree->AddTable(tblName, virtualTable, false);
+            list->Add(tblName, false, virtualTable);
         }
     }
   sqlite3_free_table(results);
+
+  FindGeometries(list);
+  ptv = list->GetFirst();
+  while (ptv != NULL)
+    {
+      // inserting items into the Tree Control View
+      if (ptv->IsView() == true)
+        TableTree->AddView(ptv->GetName(), ptv->IsGeometry(), false);
+      else
+        TableTree->AddTable(ptv->GetName(), ptv->IsVirtual(), ptv->IsGeometry(),
+                            false);
+      ptv = ptv->GetNext();
+    }
+  delete list;
+
 // fetching temporary tables and views
   sql =
     wxT
@@ -5219,6 +6817,7 @@ void MyFrame::InitTableTree()
       sqlite3_free(errMsg);
       return;
     }
+  list = new TableViewList();
   if (rows < 1)
     ;
   else
@@ -5234,12 +6833,27 @@ void MyFrame::InitTableTree()
             virtualTable = false;
           tblName = wxString::FromUTF8(name);
           if (strcmp(type, "view") == 0)
-            TableTree->AddView(tblName, true);
+            list->Add(tblName, true, false);
           else
-            TableTree->AddTable(tblName, virtualTable, true);
+            list->Add(tblName, false, virtualTable);
         }
     }
   sqlite3_free_table(results);
+
+  FindGeometries(list);
+  ptv = list->GetFirst();
+  while (ptv != NULL)
+    {
+      // inserting items into the Tree Control View
+      if (ptv->IsView() == true)
+        TableTree->AddView(ptv->GetName(), ptv->IsGeometry(), true);
+      else
+        TableTree->AddTable(ptv->GetName(), ptv->IsVirtual(), ptv->IsGeometry(),
+                            true);
+      ptv = ptv->GetNext();
+    }
+  delete list;
+
   ListAttached();
   TableTree->ExpandRoot();
   TableTree->Show(true);
@@ -5258,7 +6872,12 @@ void MyFrame::InitTableTree(wxString & dbAlias, wxString & path)
   char *type;
   wxString tblName;
   wxString sql;
+  TableViewList *list;
+  TableViewItem *ptv;
   bool virtualTable = false;
+  TableTree->DeleteAltTopologies();
+  TableTree->DeleteAltRasterCoverages();
+  TableTree->DeleteAltVectorCoverages();
   wxString dbInfos = dbAlias + wxT(": ") + path;
   wxTreeItemId db = TableTree->AppendItem(TableTree->GetRootItem(), dbInfos);
   TableTree->SetItemData(db,
@@ -5270,28 +6889,34 @@ void MyFrame::InitTableTree(wxString & dbAlias, wxString & path)
   wxTreeItemId rootIsoMetadata = TableTree->AppendItem(db, wxT("ISO Metadata"));
   wxTreeItemId rootStyling = TableTree->AppendItem(db, wxT("Styling"));
   wxTreeItemId rootTopologies = TableTree->AppendItem(db, wxT("Topologies"));
+  wxTreeItemId rootRasterCoverages =
+    TableTree->AppendItem(db, wxT("Raster Coverages"));
+  wxTreeItemId rootVectorCoverages =
+    TableTree->AppendItem(db, wxT("VectorRaster Coverages"));
   wxTreeItemId rootMetadata = TableTree->AppendItem(db, wxT("Metadata"));
   wxTreeItemId rootInternal = TableTree->AppendItem(db, wxT("Internal Data"));
   wxTreeItemId rootSpatialIndex =
     TableTree->AppendItem(db, wxT("Spatial Index"));
   TableTree->SetItemImage(rootUserData, 17);
   TableTree->SetItemImage(rootTopologies, 17);
+  TableTree->SetItemImage(rootRasterCoverages, 22);
+  TableTree->SetItemImage(rootVectorCoverages, 24);
   TableTree->SetItemImage(rootStyling, 17);
   TableTree->SetItemImage(rootIsoMetadata, 17);
   TableTree->SetItemImage(rootMetadata, 17);
   TableTree->SetItemImage(rootInternal, 17);
   TableTree->SetItemImage(rootSpatialIndex, 17);
   RootNodes nodes =
-    RootNodes(dbAlias, rootUserData, rootTopologies, rootStyling,
+    RootNodes(dbAlias, rootUserData, rootTopologies, rootRasterCoverages,
+              rootVectorCoverages, rootStyling,
               rootIsoMetadata, rootMetadata,
               rootInternal,
               rootSpatialIndex);
   if (ExistsTopologyMaster(dbAlias))
     {
-      //
+      // fetching topologies
       wxString column_list;
       GetTopologyColumns(dbAlias, &column_list);
-      // fetching topologies
       sql = wxT("SELECT ");
       sql += column_list;
       sql += wxT(" FROM ") + dbAlias + wxT(".topology_master");
@@ -5342,7 +6967,70 @@ void MyFrame::InitTableTree(wxString & dbAlias, wxString & path)
                     }
                 }
               if (topology.CheckPrefix() == true)
-                TableTree->AddTopology(rootTopologies, &topology);
+                TableTree->AddAltTopology(rootTopologies, &topology);
+            }
+        }
+      sqlite3_free_table(results);
+    }
+  if (ExistsRasterCoverages(dbAlias))
+    {
+      // fetching Raster Coverages
+      sql =
+        wxT("SELECT coverage_name, srid FROM ") + dbAlias +
+        wxT(".raster_coverages");
+      int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
+                                  &rows, &columns, &errMsg);
+      if (ret != SQLITE_OK)
+        {
+          wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+          sqlite3_free(errMsg);
+          return;
+        }
+      if (rows < 1)
+        ;
+      else
+        {
+          for (i = 1; i <= rows; i++)
+            {
+              // adding some Raster Coverage
+              const char *name = results[(i * columns) + 0];
+              int srid = atoi(results[(i * columns) + 1]);
+              RasterCoverageSet coverage(name, srid);
+              TableTree->AddAltRasterCoverage(rootRasterCoverages, &coverage);
+            }
+        }
+      sqlite3_free_table(results);
+    }
+  if (ExistsVectorCoverages(dbAlias))
+    {
+      // fetching Vector Coverages
+      sql =
+        wxT("SELECT c.coverage_name, g.srid FROM ") + dbAlias +
+        wxT(".vector_coverages AS c ");
+      sql += wxT("JOIN ") + dbAlias + wxT(".geometry_columns AS g ON (");
+      sql += wxT("Lower(c.f_table_name) = Lower(g.f_table_name) AND ");
+      sql += wxT("Lower(c.f_geometry_column) = Lower(g.f_geometry_column))");
+      int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
+                                  &rows, &columns, &errMsg);
+      if (ret != SQLITE_OK)
+        {
+          wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+          sqlite3_free(errMsg);
+          return;
+        }
+      if (rows < 1)
+        ;
+      else
+        {
+          for (i = 1; i <= rows; i++)
+            {
+              // adding some Vector Coverage
+              const char *name = results[(i * columns) + 0];
+              int srid = atoi(results[(i * columns) + 1]);
+              VectorCoverageSet coverage(name, srid);
+              TableTree->AddAltVectorCoverage(rootVectorCoverages, &coverage);
             }
         }
       sqlite3_free_table(results);
@@ -5361,6 +7049,7 @@ void MyFrame::InitTableTree(wxString & dbAlias, wxString & path)
       sqlite3_free(errMsg);
       return;
     }
+  list = new TableViewList();
   if (rows < 1)
     ;
   else
@@ -5376,12 +7065,26 @@ void MyFrame::InitTableTree(wxString & dbAlias, wxString & path)
             virtualTable = false;
           tblName = wxString::FromUTF8(name);
           if (strcmp(type, "view") == 0)
-            TableTree->AddView(dbAlias, tblName, &nodes);
+            list->Add(tblName, true, false);
           else
-            TableTree->AddTable(dbAlias, tblName, virtualTable, &nodes);
+            list->Add(tblName, false, virtualTable);
         }
     }
   sqlite3_free_table(results);
+
+  FindGeometries(dbAlias, list);
+  ptv = list->GetFirst();
+  while (ptv != NULL)
+    {
+      // inserting items into the Tree Control View
+      if (ptv->IsView() == true)
+        TableTree->AddView(dbAlias, ptv->GetName(), ptv->IsGeometry(), &nodes);
+      else
+        TableTree->AddTable(dbAlias, ptv->GetName(), ptv->IsVirtual(),
+                            ptv->IsGeometry(), &nodes);
+      ptv = ptv->GetNext();
+    }
+  delete list;
 }
 
 void MyFrame::ListAttached()
@@ -5535,30 +7238,233 @@ void MyFrame::GetTableColumns(wxString & tableName, MyTableInfo * list)
         {
           for (i = 1; i <= rows; i++)
             {
-              column = results[(i * columns) + 0];
-              if (atoi(results[(i * columns) + 1]) == 1)
-                index = true;
-              else
-                index = false;
-              if (atoi(results[(i * columns) + 1]) == 2)
-                cached = true;
-              else
-                cached = false;
-              Column = wxString::FromUTF8(column);
-              list->SetGeometry(Column, index, cached);
+              column = results[(i * columns) + 0];
+              if (atoi(results[(i * columns) + 1]) == 1)
+                index = true;
+              else
+                index = false;
+              if (atoi(results[(i * columns) + 1]) == 2)
+                cached = true;
+              else
+                cached = false;
+              Column = wxString::FromUTF8(column);
+              list->SetGeometry(Column, index, cached);
+            }
+        }
+      sqlite3_free_table(results);
+
+      if (HasVirtsMetadata() == true)
+        {
+          // may also be some VirtualShape
+          sql = wxT("SELECT virt_geometry FROM virts_geometry_columns ");
+          sql += wxT("WHERE Lower(virt_name) = Lower('");
+          strcpy(xname, tableName.ToUTF8());
+          CleanSqlString(xname);
+          sql += wxString::FromUTF8(xname);
+          sql += wxT("')");
+          ret =
+            sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results, &rows,
+                              &columns, &errMsg);
+          if (ret != SQLITE_OK)
+            {
+              wxMessageBox(wxT("SQLite SQL error: ") +
+                           wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
+                           wxOK | wxICON_ERROR, this);
+              sqlite3_free(errMsg);
+              return;
+            }
+          if (rows < 1)
+            ;
+          else
+            {
+              for (i = 1; i <= rows; i++)
+                {
+                  column = results[(i * columns) + 0];
+                  Column = wxString::FromUTF8(column);
+                  list->SetGeometry(Column, false, false);
+                }
+            }
+          sqlite3_free_table(results);
+        }
+    }
+}
+
+void MyFrame::FindGeometries(TableViewList * list)
+{
+// Finds all registered Geometries within the current DB
+  int ret;
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  wxString sql;
+  char *table;
+
+  list->PrepareSorted();
+  if (CheckMetadata() == true)
+    {
+      // ok, Spatial MetaData exists; retrieving Geometries
+      sql = wxT("SELECT f_table_name FROM main.geometry_columns");
+      ret =
+        sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results, &rows, &columns,
+                          &errMsg);
+      if (ret != SQLITE_OK)
+        {
+          wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+          sqlite3_free(errMsg);
+          return;
+        }
+      if (rows < 1)
+        ;
+      else
+        {
+          for (i = 1; i <= rows; i++)
+            {
+              table = results[(i * columns) + 0];
+              wxString tbl = wxString::FromUTF8(table);
+              list->SetGeometry(tbl);
+            }
+        }
+      sqlite3_free_table(results);
+
+      if (HasVirtsMetadata() == true)
+        {
+          // may also be some VirtualShape
+          sql = wxT("SELECT virt_name FROM main.virts_geometry_columns");
+          ret =
+            sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results, &rows,
+                              &columns, &errMsg);
+          if (ret != SQLITE_OK)
+            {
+              wxMessageBox(wxT("SQLite SQL error: ") +
+                           wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
+                           wxOK | wxICON_ERROR, this);
+              sqlite3_free(errMsg);
+              return;
+            }
+          if (rows < 1)
+            ;
+          else
+            {
+              for (i = 1; i <= rows; i++)
+                {
+                  table = results[(i * columns) + 0];
+                  wxString tbl = wxString::FromUTF8(table);
+                  list->SetGeometry(tbl);
+                }
+            }
+          sqlite3_free_table(results);
+        }
+
+      if (HasViewsMetadata() == true)
+        {
+          // ok, Spatial MetaData exists; retrieving Geometries
+          sql = wxT("SELECT view_name FROM main.views_geometry_columns");
+          ret =
+            sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results, &rows,
+                              &columns, &errMsg);
+          if (ret != SQLITE_OK)
+            {
+              wxMessageBox(wxT("SQLite SQL error: ") +
+                           wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
+                           wxOK | wxICON_ERROR, this);
+              sqlite3_free(errMsg);
+              return;
+            }
+          if (rows < 1)
+            ;
+          else
+            {
+              for (i = 1; i <= rows; i++)
+                {
+                  table = results[(i * columns) + 0];
+                  wxString tbl = wxString::FromUTF8(table);
+                  list->SetGeometry(tbl);
+                }
+            }
+          sqlite3_free_table(results);
+        }
+    }
+}
+
+void MyFrame::FindGeometries(wxString & dbAlias, TableViewList * list)
+{
+// Finds all registered Geometries within an Attached DB
+  int ret;
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  wxString sql;
+  char *table;
+
+  list->PrepareSorted();
+  if (CheckMetadata(dbAlias) == true)
+    {
+      // ok, Spatial MetaData exists; retrieving Geometries
+      sql = wxT("SELECT f_table_name FROM ");
+      sql += dbAlias + wxT(".") + wxT("geometry_columns");
+      ret =
+        sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results, &rows, &columns,
+                          &errMsg);
+      if (ret != SQLITE_OK)
+        {
+          wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+          sqlite3_free(errMsg);
+          return;
+        }
+      if (rows < 1)
+        ;
+      else
+        {
+          for (i = 1; i <= rows; i++)
+            {
+              table = results[(i * columns) + 0];
+              wxString tbl = wxString::FromUTF8(table);
+              list->SetGeometry(tbl);
+            }
+        }
+      sqlite3_free_table(results);
+
+      if (HasVirtsMetadata(dbAlias) == true)
+        {
+          // may also be some VirtualShape
+          sql = wxT("SELECT virt_name FROM ");
+          sql += dbAlias + wxT(".") + wxT("virts_geometry_columns");
+          ret =
+            sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results, &rows,
+                              &columns, &errMsg);
+          if (ret != SQLITE_OK)
+            {
+              wxMessageBox(wxT("SQLite SQL error: ") +
+                           wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
+                           wxOK | wxICON_ERROR, this);
+              sqlite3_free(errMsg);
+              return;
+            }
+          if (rows < 1)
+            ;
+          else
+            {
+              for (i = 1; i <= rows; i++)
+                {
+                  table = results[(i * columns) + 0];
+                  wxString tbl = wxString::FromUTF8(table);
+                  list->SetGeometry(tbl);
+                }
             }
+          sqlite3_free_table(results);
         }
-      sqlite3_free_table(results);
 
-      if (HasVirtsMetadata() == true)
+      if (HasViewsMetadata(dbAlias) == true)
         {
-          // may also be some VirtualShape
-          sql = wxT("SELECT virt_geometry FROM virts_geometry_columns ");
-          sql += wxT("WHERE Lower(virt_name) = Lower('");
-          strcpy(xname, tableName.ToUTF8());
-          CleanSqlString(xname);
-          sql += wxString::FromUTF8(xname);
-          sql += wxT("')");
+          // ok, Spatial MetaData exists; retrieving Geometries
+          sql = wxT("SELECT view_name FROM ");
+          sql += dbAlias + wxT(".") + wxT("views_geometry_columns");
           ret =
             sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results, &rows,
                               &columns, &errMsg);
@@ -5576,9 +7482,9 @@ void MyFrame::GetTableColumns(wxString & tableName, MyTableInfo * list)
             {
               for (i = 1; i <= rows; i++)
                 {
-                  column = results[(i * columns) + 0];
-                  Column = wxString::FromUTF8(column);
-                  list->SetGeometry(Column, false, false);
+                  table = results[(i * columns) + 0];
+                  wxString tbl = wxString::FromUTF8(table);
+                  list->SetGeometry(tbl);
                 }
             }
           sqlite3_free_table(results);
@@ -5953,13 +7859,12 @@ void MyFrame::GetViewTriggers(wxString & tableName, MyViewInfo * list)
   wxString Name;
   wxString sql;
   char xname[1024];
-  sql =
-    wxT
-    ("SELECT name FROM sqlite_master WHERE type = 'trigger' AND tbl_name = '");
+  sql = wxT("SELECT name FROM sqlite_master WHERE type = 'trigger' ");
+  sql += wxT("AND Lower(tbl_name) = Lower('");
   strcpy(xname, tableName.ToUTF8());
   CleanSqlString(xname);
   sql += wxString::FromUTF8(xname);
-  sql += wxT("' ORDER BY name");
+  sql += wxT("') ORDER BY name");
   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
                               &rows, &columns, &errMsg);
   if (ret != SQLITE_OK)
@@ -6414,13 +8319,12 @@ void MyFrame::GetTableTriggers(wxString & tableName, MyTableInfo * list)
   wxString Name;
   wxString sql;
   char xname[1024];
-  sql =
-    wxT
-    ("SELECT name FROM sqlite_master WHERE type = 'trigger' AND tbl_name = '");
+  sql = wxT("SELECT name FROM sqlite_master WHERE type = 'trigger' ");
+  sql += wxT("AND Lower(tbl_name) = Lower('");
   strcpy(xname, tableName.ToUTF8());
   CleanSqlString(xname);
   sql += wxString::FromUTF8(xname);
-  sql += wxT("' ORDER BY name");
+  sql += wxT("') ORDER BY name");
   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
                               &rows, &columns, &errMsg);
   if (ret != SQLITE_OK)
@@ -6524,51 +8428,254 @@ wxString *MyFrame::GetColumnNames(wxString & tableName, int *n_cols)
       cols = new wxString[rows];
       for (i = 1; i <= rows; i++)
         {
-          column = results[(i * columns) + 1];
-          *(cols + i - 1) += wxString::FromUTF8(column);
+          column = results[(i * columns) + 1];
+          *(cols + i - 1) += wxString::FromUTF8(column);
+        }
+    }
+  sqlite3_free_table(results);
+  *n_cols = nCols;
+  return cols;
+}
+
+int MyFrame::GetCharsetIndex(wxString & charset)
+{
+// identifies the INDEX for a given charset
+  int i;
+  for (i = 0; i < CharsetsLen; i++)
+    {
+      if (*(Charsets + i) == charset)
+        return i;
+    }
+  return wxNOT_FOUND;
+}
+
+wxString & MyFrame::GetCharsetName(wxString & charset)
+{
+// identifies the full name for a given charset code
+  int i;
+  for (i = 0; i < CharsetsLen; i++)
+    {
+      if (*(Charsets + i) == charset)
+        return *(CharsetsNames + i);
+    }
+  return charset;
+}
+
+void MyFrame::ClearTableTree()
+{
+// resets the table TREE list to the empty state
+  wxString path = wxT("no current DB");
+  TableTree->SetPath(path);
+  TableTree->FlushAll();
+}
+
+void MyFrame::AutoFDOStart()
+{
+//
+// trying to start the FDO-OGR auto-wrapper
+//
+  int ret;
+  const char *name;
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char sql[1024];
+  int count = 0;
+  int len;
+  int spatial_type = 0;
+  AutoFDOTables tables;
+  AutoFDOTable *p;
+  wxString fdoNames[5];
+  char xname[1024];
+  char xname2[1024];
+  SpatiaLiteMetadata = false;
+  AutoFDOmsg = wxT("");
+  strcpy(sql, "SELECT CheckSpatialMetadata()");
+  ret = sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
+  if (ret != SQLITE_OK)
+    goto error1;
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        spatial_type = atoi(results[(i * columns) + 0]);
+    }
+  sqlite3_free_table(results);
+error1:
+  if (spatial_type == 1 || spatial_type == 3)
+    SpatiaLiteMetadata = true;
+  if (spatial_type == 2)
+    {
+      //
+      // ok, creating VirtualFDO tables 
+      //
+      strcpy(sql, "SELECT DISTINCT f_table_name FROM geometry_columns");
+      ret =
+        sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
+      if (ret != SQLITE_OK)
+        goto error;
+      if (rows < 1)
+        ;
+      else
+        {
+          for (i = 1; i <= rows; i++)
+            {
+              name = results[(i * columns) + 0];
+              if (name)
+                {
+                  len = strlen(name);
+                  tables.Add(name, len);
+                }
+            }
+        }
+      sqlite3_free_table(results);
+      p = tables.GetFirst();
+      while (p)
+        {
+          //
+          // destroying the VirtualFDO table [if existing] 
+          //
+          sprintf(xname, "fdo_%s", p->GetName());
+          DoubleQuotedSql(xname);
+          sprintf(sql, "DROP TABLE IF EXISTS %s", xname);
+          ret = sqlite3_exec(SqliteHandle, sql, NULL, 0, NULL);
+          if (ret != SQLITE_OK)
+            goto error;
+          //
+          // creating the VirtualFDO table 
+          //
+          sprintf(xname, "fdo_%s", p->GetName());
+          DoubleQuotedSql(xname);
+          strcpy(xname2, p->GetName());
+          DoubleQuotedSql(xname2);
+          sprintf(sql, "CREATE VIRTUAL TABLE %s USING VirtualFDO(%s)",
+                  xname, xname2);
+          ret = sqlite3_exec(SqliteHandle, sql, NULL, 0, NULL);
+          if (ret != SQLITE_OK)
+            goto error;
+          if (count < 5)
+            fdoNames[count] =
+              wxT("- VirtualTable: fdo_") + wxString::FromUTF8(p->GetName());
+          else
+            fdoNames[4] = wxT("- ... and others ...");
+          count++;
+          p = p->GetNext();
+        }
+    error:
+      if (count)
+        {
+          AutoFDOmsg =
+            wxT("FDO-OGR detected; activating FDO-OGR auto-wrapping ...\n\n");
+          if (fdoNames[0].Len() > 0)
+            AutoFDOmsg += fdoNames[0] + wxT("\n");
+          if (fdoNames[1].Len() > 0)
+            AutoFDOmsg += fdoNames[1] + wxT("\n");
+          if (fdoNames[2].Len() > 0)
+            AutoFDOmsg += fdoNames[2] + wxT("\n");
+          if (fdoNames[3].Len() > 0)
+            AutoFDOmsg += fdoNames[3] + wxT("\n");
+          if (fdoNames[4].Len() > 0)
+            AutoFDOmsg += fdoNames[4] + wxT("\n");
+          AutoFDOmsg +=
+            wxT
+            ("\nAccessing these fdo_XX tables you can take full advantage of\n");
+          AutoFDOmsg += wxT("FDO-OGR auto-wrapping facility\n");
+          AutoFDOmsg +=
+            wxT
+            ("This allows you to access any specific FDO-OGR Geometry as if it\n");
+          AutoFDOmsg +=
+            wxT
+            ("where native SpatiaLite ones in a completely transparent way.\n");
+        }
+      return;
+    }
+}
+
+void MyFrame::AutoFDOStop()
+{
+//
+// trying to stop the FDO-OGR auto-wrapper
+//
+  int ret;
+  const char *name;
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char sql[1024];
+  int count = 0;
+  int len;
+  int spatial_type = 0;
+  char xname[1024];
+  AutoFDOTables tables;
+  AutoFDOTable *p;
+  AutoFDOmsg = wxT("");
+  strcpy(sql, "SELECT CheckSpatialMetadata()");
+  ret = sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
+  if (ret != SQLITE_OK)
+    goto error1;
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        spatial_type = atoi(results[(i * columns) + 0]);
+    }
+  sqlite3_free_table(results);
+error1:
+  if (spatial_type == 2)
+    {
+      //
+      // ok, destroying VirtualFDO tables 
+      //
+      strcpy(sql, "SELECT DISTINCT f_table_name FROM geometry_columns");
+      ret =
+        sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
+      if (ret != SQLITE_OK)
+        goto error;
+      if (rows < 1)
+        ;
+      else
+        {
+          for (i = 1; i <= rows; i++)
+            {
+              name = results[(i * columns) + 0];
+              if (name)
+                {
+                  len = strlen(name);
+                  tables.Add(name, len);
+                }
+            }
+        }
+      sqlite3_free_table(results);
+      p = tables.GetFirst();
+      while (p)
+        {
+          //
+          // destroying the VirtualFDO table [if existing] 
+          //
+          sprintf(xname, "fdo_%s", p->GetName());
+          DoubleQuotedSql(xname);
+          sprintf(sql, "DROP TABLE IF EXISTS %s", xname);
+          ret = sqlite3_exec(SqliteHandle, sql, NULL, 0, NULL);
+          if (ret != SQLITE_OK)
+            goto error;
+          count++;
+          p = p->GetNext();
         }
+    error:
+      if (count)
+        AutoFDOmsg = wxT("FDO-OGR auto-wrapping shutdown done");
+      return;
     }
-  sqlite3_free_table(results);
-  *n_cols = nCols;
-  return cols;
-}
-
-int MyFrame::GetCharsetIndex(wxString & charset)
-{
-// identifies the INDEX for a given charset
-  int i;
-  for (i = 0; i < CharsetsLen; i++)
-    {
-      if (*(Charsets + i) == charset)
-        return i;
-    }
-  return wxNOT_FOUND;
-}
-
-wxString & MyFrame::GetCharsetName(wxString & charset)
-{
-// identifies the full name for a given charset code
-  int i;
-  for (i = 0; i < CharsetsLen; i++)
-    {
-      if (*(Charsets + i) == charset)
-        return *(CharsetsNames + i);
-    }
-  return charset;
-}
-
-void MyFrame::ClearTableTree()
-{
-// resets the table TREE list to the empty state
-  wxString path = wxT("no current DB");
-  TableTree->SetPath(path);
-  TableTree->FlushAll();
 }
 
-void MyFrame::AutoFDOStart()
+void MyFrame::AutoGPKGStart()
 {
 //
-// trying to start the FDO-OGR auto-wrapper
+// trying to start the OGC GeoPackage auto-wrapper
 //
   int ret;
   const char *name;
@@ -6579,15 +8686,14 @@ void MyFrame::AutoFDOStart()
   char sql[1024];
   int count = 0;
   int len;
-  int spatial_type = 0;
-  AutoFDOTables tables;
-  AutoFDOTable *p;
-  wxString fdoNames[5];
+  int is_gpkg = 0;
+  AutoGPKGTables tables;
+  AutoGPKGTable *p;
+  wxString gpkgNames[5];
   char xname[1024];
   char xname2[1024];
-  SpatiaLiteMetadata = false;
-  AutoFDOmsg = wxT("");
-  strcpy(sql, "SELECT CheckSpatialMetadata()");
+  AutoGPKGmsg = wxT("");
+  strcpy(sql, "SELECT CheckGeoPackageMetadata()");
   ret = sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
   if (ret != SQLITE_OK)
     goto error1;
@@ -6596,18 +8702,16 @@ void MyFrame::AutoFDOStart()
   else
     {
       for (i = 1; i <= rows; i++)
-        spatial_type = atoi(results[(i * columns) + 0]);
+        is_gpkg = atoi(results[(i * columns) + 0]);
     }
   sqlite3_free_table(results);
 error1:
-  if (spatial_type == 1 || spatial_type == 3)
-    SpatiaLiteMetadata = true;
-  if (spatial_type == 2)
+  if (is_gpkg)
     {
       //
-      // ok, creating VirtualFDO tables 
+      // ok, creating VirtualGPKG tables 
       //
-      strcpy(sql, "SELECT DISTINCT f_table_name FROM geometry_columns");
+      strcpy(sql, "SELECT DISTINCT table_name FROM gpkg_geometry_columns");
       ret =
         sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
       if (ret != SQLITE_OK)
@@ -6631,57 +8735,58 @@ error1:
       while (p)
         {
           //
-          // destroying the VirtualFDO table [if existing] 
+          // destroying the VirtualGPKG table [if existing] 
           //
-          sprintf(xname, "fdo_%s", p->GetName());
+          sprintf(xname, "vgpkg_%s", p->GetName());
           DoubleQuotedSql(xname);
           sprintf(sql, "DROP TABLE IF EXISTS %s", xname);
           ret = sqlite3_exec(SqliteHandle, sql, NULL, 0, NULL);
           if (ret != SQLITE_OK)
             goto error;
           //
-          // creating the VirtualFDO table 
+          // creating the VirtualGPKG table 
           //
-          sprintf(xname, "fdo_%s", p->GetName());
+          sprintf(xname, "vgpkg_%s", p->GetName());
           DoubleQuotedSql(xname);
           strcpy(xname2, p->GetName());
           DoubleQuotedSql(xname2);
-          sprintf(sql, "CREATE VIRTUAL TABLE %s USING VirtualFDO(%s)",
+          sprintf(sql, "CREATE VIRTUAL TABLE %s USING VirtualGPKG(%s)",
                   xname, xname2);
           ret = sqlite3_exec(SqliteHandle, sql, NULL, 0, NULL);
           if (ret != SQLITE_OK)
             goto error;
           if (count < 5)
-            fdoNames[count] =
-              wxT("- VirtualTable: fdo_") + wxString::FromUTF8(p->GetName());
+            gpkgNames[count] =
+              wxT("- VirtualTable: vgpg_") + wxString::FromUTF8(p->GetName());
           else
-            fdoNames[4] = wxT("- ... and others ...");
+            gpkgNames[4] = wxT("- ... and others ...");
           count++;
           p = p->GetNext();
         }
     error:
-      if (count++)
+      if (count)
         {
-          AutoFDOmsg =
-            wxT("FDO-OGR detected; activating FDO-OGR auto-wrapping ...\n\n");
-          if (fdoNames[0].Len() > 0)
-            AutoFDOmsg += fdoNames[0] + wxT("\n");
-          if (fdoNames[1].Len() > 0)
-            AutoFDOmsg += fdoNames[1] + wxT("\n");
-          if (fdoNames[2].Len() > 0)
-            AutoFDOmsg += fdoNames[2] + wxT("\n");
-          if (fdoNames[3].Len() > 0)
-            AutoFDOmsg += fdoNames[3] + wxT("\n");
-          if (fdoNames[4].Len() > 0)
-            AutoFDOmsg += fdoNames[4] + wxT("\n");
-          AutoFDOmsg +=
+          AutoGPKGmsg =
             wxT
-            ("\nAccessing these fdo_XX tables you can take full advantage of\n");
-          AutoFDOmsg += wxT("FDO-OGR auto-wrapping facility\n");
-          AutoFDOmsg +=
+            ("GPKG detected; activating OGC GeoPackage auto-wrapping ...\n\n");
+          if (gpkgNames[0].Len() > 0)
+            AutoGPKGmsg += gpkgNames[0] + wxT("\n");
+          if (gpkgNames[1].Len() > 0)
+            AutoGPKGmsg += gpkgNames[1] + wxT("\n");
+          if (gpkgNames[2].Len() > 0)
+            AutoGPKGmsg += gpkgNames[2] + wxT("\n");
+          if (gpkgNames[3].Len() > 0)
+            AutoGPKGmsg += gpkgNames[3] + wxT("\n");
+          if (gpkgNames[4].Len() > 0)
+            AutoGPKGmsg += gpkgNames[4] + wxT("\n");
+          AutoGPKGmsg +=
             wxT
-            ("This allows you to access any specific FDO-OGR Geometry as if it\n");
-          AutoFDOmsg +=
+            ("\nAccessing these vgpkg_XX tables you can take full advantage of\n");
+          AutoGPKGmsg += wxT("OGC GeoPackage auto-wrapping facility\n");
+          AutoGPKGmsg +=
+            wxT
+            ("This allows you to access any specific GPKG Geometry as if it\n");
+          AutoGPKGmsg +=
             wxT
             ("where native SpatiaLite ones in a completely transparent way.\n");
         }
@@ -6689,10 +8794,10 @@ error1:
     }
 }
 
-void MyFrame::AutoFDOStop()
+void MyFrame::AutoGPKGStop()
 {
 //
-// trying to stop the FDO-OGR auto-wrapper
+// trying to stop the OGC GeoPackage auto-wrapper
 //
   int ret;
   const char *name;
@@ -6703,12 +8808,12 @@ void MyFrame::AutoFDOStop()
   char sql[1024];
   int count = 0;
   int len;
-  int spatial_type = 0;
+  int is_gpkg = 0;
   char xname[1024];
-  AutoFDOTables tables;
-  AutoFDOTable *p;
-  AutoFDOmsg = wxT("");
-  strcpy(sql, "SELECT CheckSpatialMetadata()");
+  AutoGPKGTables tables;
+  AutoGPKGTable *p;
+  AutoGPKGmsg = wxT("");
+  strcpy(sql, "SELECT CheckGeoPackageMetadata()");
   ret = sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
   if (ret != SQLITE_OK)
     goto error1;
@@ -6717,16 +8822,16 @@ void MyFrame::AutoFDOStop()
   else
     {
       for (i = 1; i <= rows; i++)
-        spatial_type = atoi(results[(i * columns) + 0]);
+        is_gpkg = atoi(results[(i * columns) + 0]);
     }
   sqlite3_free_table(results);
 error1:
-  if (spatial_type == 2)
+  if (is_gpkg)
     {
       //
-      // ok, destroying VirtualFDO tables 
+      // ok, destroying VirtualGPKG tables 
       //
-      strcpy(sql, "SELECT DISTINCT f_table_name FROM geometry_columns");
+      strcpy(sql, "SELECT DISTINCT table_name FROM gpkg_geometry_columns");
       ret =
         sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
       if (ret != SQLITE_OK)
@@ -6750,9 +8855,9 @@ error1:
       while (p)
         {
           //
-          // destroying the VirtualFDO table [if existing] 
+          // destroying the VirtualGPKG table [if existing] 
           //
-          sprintf(xname, "fdo_%s", p->GetName());
+          sprintf(xname, "vgpkg_%s", p->GetName());
           DoubleQuotedSql(xname);
           sprintf(sql, "DROP TABLE IF EXISTS %s", xname);
           ret = sqlite3_exec(SqliteHandle, sql, NULL, 0, NULL);
@@ -6762,8 +8867,8 @@ error1:
           p = p->GetNext();
         }
     error:
-      if (count++)
-        AutoFDOmsg = wxT("FDO-OGR auto-wrapping shutdown done");
+      if (count)
+        AutoGPKGmsg = wxT("OGC GeoPackage auto-wrapping shutdown done");
       return;
     }
 }
@@ -7138,7 +9243,7 @@ bool MyFrame::ExistsTopologyMaster()
   wxString sql;
   int count = 0;
 
-  sql = wxT("SELECT Count(*) FROM sqlite_master ");
+  sql = wxT("SELECT Count(*) FROM main.sqlite_master ");
   sql += wxT("WHERE type = 'table' AND ");
   sql += wxT("tbl_name = 'topology_master'");
   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
@@ -7274,7 +9379,170 @@ void MyFrame::GetTopologyColumns(wxString & dbAlias, wxString * list)
       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
       sqlite3_free(errMsg);
-      return;
+      return;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          name = results[(i * columns) + 1];
+          if (comma == false)
+            comma = true;
+          else
+            col_list += wxT(", ");
+          col_list += wxString::FromUTF8(name);
+        }
+    }
+  sqlite3_free_table(results);
+  *list = col_list;
+}
+
+bool MyFrame::ExistsRasterCoverages()
+{
+//
+// checking if RASTER_COVERAGES exists
+//
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  wxString sql;
+  int count = 0;
+
+  sql = wxT("SELECT Count(*) FROM main.sqlite_master ");
+  sql += wxT("WHERE type = 'table' AND ");
+  sql += wxT("tbl_name = 'raster_coverages'");
+  int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
+                              &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return false;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          count = atoi(results[(i * columns) + 0]);
+        }
+    }
+  sqlite3_free_table(results);
+  if (count)
+    return true;
+  return false;
+}
+
+bool MyFrame::ExistsRasterCoverages(wxString & dbAlias)
+{
+//
+// checking if RASTER_COVERAGES exists [Attached DB]
+//
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  wxString sql;
+  int count = 0;
+
+  sql = wxT("SELECT Count(*) FROM ") + dbAlias + wxT(".sqlite_master ");
+  sql += wxT("WHERE type = 'table' AND ");
+  sql += wxT("tbl_name = 'raster_coverages'");
+  int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
+                              &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return false;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          count = atoi(results[(i * columns) + 0]);
+        }
+    }
+  sqlite3_free_table(results);
+  if (count)
+    return true;
+  return false;
+}
+
+bool MyFrame::ExistsVectorCoverages()
+{
+//
+// checking if VECTOR_COVERAGES exists
+//
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  wxString sql;
+  int count = 0;
+
+  sql = wxT("SELECT Count(*) FROM main.sqlite_master ");
+  sql += wxT("WHERE type = 'table' AND ");
+  sql += wxT("tbl_name = 'vector_coverages'");
+  int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
+                              &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return false;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          count = atoi(results[(i * columns) + 0]);
+        }
+    }
+  sqlite3_free_table(results);
+  if (count)
+    return true;
+  return false;
+}
+
+bool MyFrame::ExistsVectorCoverages(wxString & dbAlias)
+{
+//
+// checking if VECTOR_COVERAGES exists [Attached DB]
+//
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  wxString sql;
+  int count = 0;
+
+  sql = wxT("SELECT Count(*) FROM ") + dbAlias + wxT(".sqlite_master ");
+  sql += wxT("WHERE type = 'table' AND ");
+  sql += wxT("tbl_name = 'vector_coverages'");
+  int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
+                              &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return false;
     }
   if (rows < 1)
     ;
@@ -7282,16 +9550,13 @@ void MyFrame::GetTopologyColumns(wxString & dbAlias, wxString * list)
     {
       for (i = 1; i <= rows; i++)
         {
-          name = results[(i * columns) + 1];
-          if (comma == false)
-            comma = true;
-          else
-            col_list += wxT(", ");
-          col_list += wxString::FromUTF8(name);
+          count = atoi(results[(i * columns) + 0]);
         }
     }
   sqlite3_free_table(results);
-  *list = col_list;
+  if (count)
+    return true;
+  return false;
 }
 
 void MyFrame::CheckIfExists(const char *name, bool * table, bool * view)
@@ -7429,6 +9694,8 @@ void MyFrame::InsertIntoLog(wxString & sql_stmt)
   char *clean;
   int ret;
   char *errMsg = NULL;
+  if (ReadOnlyConnection)
+    return;
   wxString sql = wxT("INSERT INTO sql_statements_log ");
   sql += wxT("(id, time_start, user_agent, sql_statement) VALUES (");
   sql += wxT("NULL, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), ");
@@ -7457,6 +9724,8 @@ void MyFrame::UpdateLog()
   char dummy[64];
   int ret;
   char *errMsg = NULL;
+  if (ReadOnlyConnection)
+    return;
   wxString sql = wxT("UPDATE sql_statements_log SET ");
   sql += wxT("time_end = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), ");
   sql += wxT("success = 1, error_cause = 'success' ");
@@ -7485,6 +9754,8 @@ void MyFrame::UpdateLog(wxString & error_msg)
   char *clean;
   int ret;
   char *errMsg = NULL;
+  if (ReadOnlyConnection)
+    return;
   wxString sql = wxT("UPDATE sql_statements_log SET ");
   sql += wxT("time_end = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), ");
   sql += wxT("success = 0, error_cause = '");
@@ -7515,6 +9786,8 @@ void MyFrame::UpdateAbortedLog()
   char dummy[64];
   int ret;
   char *errMsg = NULL;
+  if (ReadOnlyConnection)
+    return;
   wxString sql = wxT("UPDATE sql_statements_log SET ");
   sql += wxT("time_end = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), ");
   sql += wxT("success = 0, error_cause = 'aborted by the user' ");
@@ -7696,6 +9969,164 @@ bool MyFrame::IsDotCommandDumpShp(const char *stmt, char *table,
   return false;
 }
 
+void MyFrame::CheckGPKG(wxString & tableName, MyTableInfo * list)
+{
+// testing form PGPG virtual-geometry
+  if (tableName.StartsWith(wxT("vgpkg_")) == false)
+    return;
+  list->CheckGPKG(this, SqliteHandle, tableName);
+}
+
+void MyFrame::ResetSecurity()
+{
+// resetting the Security level
+  if (Old_SPATIALITE_SECURITY_ENV != NULL)
+    {
+#ifdef _WIN32
+      char *env = sqlite3_mprintf("SPATIALITE_SECURITY=%s",
+                                  Old_SPATIALITE_SECURITY_ENV);
+      putenv(env);
+      sqlite3_free(env);
+#else /* not WIN32 */
+      setenv("SPATIALITE_SECURITY", Old_SPATIALITE_SECURITY_ENV, 1);
+#endif
+  } else
+    {
+#ifdef _WIN32
+      putenv("SPATIALITE_SECURITY=");
+#else /* not WIN32 */
+      unsetenv("SPATIALITE_SECURITY");
+#endif
+    }
+}
+
+void MyFrame::SetSecurityRelaxed()
+{
+// enabling SPATIALIRE_SECURITY=relaxed
+  Old_SPATIALITE_SECURITY_ENV = getenv("SPATIALITE_SECURITY");
+#ifdef _WIN32
+  putenv("SPATIALITE_SECURITY=relaxed");
+#else /* not WIN32 */
+  setenv("SPATIALITE_SECURITY", "relaxed", 1);
+#endif
+  SecurityRelaxed = true;
+}
+
+void MyFrame::TestSecurityRelaxed(const char *path)
+{
+// testing for an appropriate security level
+  if (IsSafeDB(path) == true)
+    SetSecurityRelaxed();
+}
+
+bool MyFrame::IsSafeDB(const char *path)
+{
+// testing an existing DB for safety
+  int ret;
+  sqlite3 *handle;
+  char **results;
+  int rows;
+  int columns;
+  int i;
+  int count = 1;
+  void *cache = NULL;
+  ret = sqlite3_open_v2(path, &handle, SQLITE_OPEN_READONLY, NULL);
+  if (ret)
+    {
+      // an error occurred
+      sqlite3_close(handle);
+      return false;
+    }
+// setting up the internal cache
+  cache = spatialite_alloc_connection();
+  spatialite_init_ex(handle, cache, 0);
+  ret = sqlite3_get_table(handle, "SELECT CountUnsafeTriggers()", &results,
+                          &rows, &columns, NULL);
+  if (ret != SQLITE_OK)
+    {
+      // an error occurred
+      sqlite3_close(handle);
+      return false;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          const char *value = results[(i * columns) + 0];
+          count = atoi(value);
+        }
+    }
+  sqlite3_free_table(results);
+  sqlite3_close(handle);
+  spatialite_cleanup_ex(cache);
+  if (count == 0)
+    return true;
+  wxString msg = wxT("SECURITY ALERT !!!\n\n");
+  msg +=
+    wxT
+    ("The currently connected DB-file contains one or more harmful Triggers.\n");
+  msg +=
+    wxT("Such a condition could eventually cause serious security breaches.");
+  wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_EXCLAMATION, this);
+  return false;
+}
+
+MyStatusBar::MyStatusBar(MyFrame * parent):wxStatusBar(parent)
+{
+// constructor
+  Parent = parent;
+  int widths[2];
+  widths[0] = 20;
+  widths[1] = -1;
+  SetFieldsCount(2);
+  SetStatusWidths(2, widths);
+  Bitmap = new wxStaticBitmap(this, wxID_ANY, wxIcon(disconnect_xpm));
+// setting up the event handlers
+  Connect(wxID_ANY, wxEVT_SIZE, (wxObjectEventFunction) & MyStatusBar::OnSize);
+}
+
+void MyStatusBar::OnSize(wxSizeEvent & WXUNUSED(event))
+{
+//
+// this window has changed its size
+//
+  wxRect rect;
+  GetFieldRect(0, rect);
+  wxSize size = Bitmap->GetSize();
+  Bitmap->Move(rect.x + (rect.width - size.x) / 2,
+               rect.y + (rect.height - size.y) / 2);
+}
+
+void MyStatusBar::SetSecurityRelaxedIcon()
+{
+  Bitmap->SetIcon(wxIcon(security_relaxed_xpm));
+}
+
+void MyStatusBar::SetSecurityStrongIcon()
+{
+  Bitmap->SetIcon(wxIcon(security_lock_xpm));
+}
+
+void MyStatusBar::SetReadOnlyIcon()
+{
+  Bitmap->SetIcon(wxIcon(security_rdonly_xpm));
+}
+
+void MyStatusBar::SetNotConnectedIcon()
+{
+  Bitmap->SetIcon(wxIcon(disconnect_xpm));
+}
+
+void MyStatusBar::SetText(wxString & msg)
+{
+  wxStatusBar *sb = Parent->GetStatusBar();
+  if (!sb)
+    return;
+  sb->SetStatusText(msg, 1);
+}
+
 void MyFrame::GetHelp(wxString & html)
 {
 //
@@ -7735,8 +10166,14 @@ void MyFrame::GetHelp(wxString & html)
   html += wxT("<li><a href=\"#math\">math functions</a></li>");
   html +=
     wxT
+    ("<li><a href=\"#error\">SQL functions reporting GEOS / LWGEOM errors and warnings</a></li>");
+  html +=
+    wxT
     ("<li><a href=\"#length_cvt\">length/distance unit-conversion functions</a></li>");
   html +=
+    wxT
+    ("<li><a href=\"#dms_cvt\">DD/DMS conversion functions (longitude/latitude)</a></li>");
+  html +=
     wxT("<li><a href=\"#blob\">utility functions for BLOB objects</a></li>");
   html +=
     wxT
@@ -7789,6 +10226,9 @@ void MyFrame::GetHelp(wxString & html)
     ("<li><a href=\"#c43\">functions for Spatial-MetaData and Spatial-Index handling</a></li>");
   html +=
     wxT
+    ("<li><a href=\"#c43metacatalog\">functions for MetaCatalog and related Statistics</a></li>");
+  html +=
+    wxT
     ("<li><a href=\"#c43style\">functions supporting SLD/SE Styled Layers</a></li>");
   html +=
     wxT
@@ -8351,6 +10791,12 @@ void MyFrame::GetHelp(wxString & html)
     wxT
     ("<td bgcolor=\"#f0fff0\">returns the current SpatiaLite version</td></tr>");
   html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">spatialite_target_cpu( void ) : String</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">returns the current SpatiaLite Target CPU</td></tr>");
+  html +=
     wxT("<tr><td bgcolor=\"#fffff0\">proj4_version( void ) : String</td>");
   html +=
     wxT
@@ -8460,16 +10906,77 @@ void MyFrame::GetHelp(wxString & html)
   html +=
     wxT
     ("<td bgcolor=\"#f0fff0\">returns a Version 4 (random) UUID (<b>Universally unique identifier</b>).</td></tr>");
-  html += wxT("<tr><td bgcolor=\"#fffff0\">MD5Checksum( BLOB | TEXT ) : Text</td>");
+  html +=
+    wxT("<tr><td bgcolor=\"#fffff0\">MD5Checksum( BLOB | TEXT ) : Text</td>");
   html +=
     wxT
     ("<td bgcolor=\"#f0fff0\">returns the MD5 checksum corresponding to the input value.<br>Will return NULL for non-BLOB input.</td></tr>");
-  html += wxT("<tr><td bgcolor=\"#fffff0\">MD5TotalChecksum( BLOB | TEXT ) : Text</td>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">MD5TotalChecksum( BLOB | TEXT ) : Text</td>");
   html +=
     wxT
     ("<td bgcolor=\"#f0fff0\">returns a cumulative MD5 checksum.<br><b><u>Aggregate function</u></b>.</td></tr>");
   html +=
     wxT
+    ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"error\">SQL functions reporting ");
+  html += wxT("GEOS / LWGEOM errors and warnings</a></a>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">GEOS_GetLastWarningMsg( void ) : <i>String</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Will return the most recent warning message returned by GEOS (if any).<hr>");
+  html +=
+    wxT("NULL will be returned if there is no pending GEOS warning.</td></tr>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">GEOS_GetLastErrorMsg( void ) : String</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Will return the most recent error message returned by GEOS (if any).<hr>");
+  html +=
+    wxT("NULL will be returned if there is no pending GEOS error.</td></tr>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">GEOS_GetLastAuxErrorMsg( void ) : String</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Will return the most recent (auxiliary) error message returned by GEOS (if any).<hr>");
+  html +=
+    wxT
+    ("NULL will be returned if there is no pending GEOS (auxiliary) error.</td></tr>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">GEOS_GetCriticalPointFromMsg( void ) : Point<hr>");
+  html += wxT("GEOS_GetCriticalPointFromMsg( SRID Integer ) : Point</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Will (possibly) return a Point Geometry extracted from the latest error / warning ");
+  html +=
+    wxT
+    ("message returned by GEOS.<hr>NULL will be returned if there is no pending GEOS message, or if the ");
+  html +=
+    wxT("current GEOS message doesn't contain a critical Point.</td></tr>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">LWGEOM_GetLastWarningMsg( void ) : String</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Will return the most recent warning message returned by LWGEOM (if any).<hr>");
+  html +=
+    wxT("NULL will be returned if there is no pending LWGEOM error.</td></tr>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">LWGEOM_GetLastErrorMsg( void ) : String</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Will return the most recent error message returned by LWGEOM (if any).<hr>");
+  html +=
+    wxT("NULL will be returned if there is no pending LWGEOM error.</td></tr>");
+  html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
+  html +=
+    wxT
     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"math\">SQL math functions</a></a>");
   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
   html +=
@@ -8597,12 +11104,6 @@ void MyFrame::GetHelp(wxString & html)
     ("<td bgcolor=\"#f0fff0\">returns the argument <i>x</i>, converted from degrees to radians</td></tr>");
   html +=
     wxT
-    ("<tr><td bgcolor=\"#fffff0\">Round( x Double precision ) : Double precision</td>");
-  html +=
-    wxT
-    ("<td bgcolor=\"#f0fff0\">returns the integer value nearest to <i>x</i></td></tr>");
-  html +=
-    wxT
     ("<tr><td bgcolor=\"#fffff0\">Sign( x Double precision ) : Double precision</td>");
   html +=
     wxT
@@ -8749,6 +11250,24 @@ void MyFrame::GetHelp(wxString & html)
   html += wxT("<td bgcolor=\"#f0fff0\">meters / indian chains</td></tr>");
   html +=
     wxT
+    ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"dms_cvt\">DD/DMS conversion functions (longitude/latitude)</a></a>");
+  html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">LongLatToDMS( longitude Double precision , latitude Double precision ) : String</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">will return a DMS string (Degrees, Minutes and Seconds) starting from DD (Decimal Degrees) input coordinates<hr>");
+  html += wxT("NULL will be returned on invalid input.</td></tr>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">LongitudeFromDMS( dms_expression String ) : Double precision<hr>LatitudeFromDMS( dms_expression String ) : Double precision</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">will return the DD coordinates from within a DMS expression<hr>");
+  html += wxT("NULL will be returned on invalid input.</td></tr>");
+  html +=
+    wxT
     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"blob\">SQL utility functions for BLOB objects</a></a>");
   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
   html +=
@@ -9080,6 +11599,30 @@ void MyFrame::GetHelp(wxString & html)
   html += wxT("NULL will be returned if any error is encountered</td></tr>");
   html +=
     wxT
+    ("<tr><td bgcolor=\"#fffff0\">MakePolygon( geom1 Geometry [ , geom2 Geometry ]  ) : Geometry<hr>");
+  html +=
+    wxT
+    ("ST_MakePolygon( geom1 Geometry [ , geom2 Geometry ]  ) : Geometry</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Kind of lightweight/simplified ST_BuildArea: the first input Geometry is always ");
+  html +=
+    wxT
+    ("expected to represent a closed LINESTRING assumed to identify the output polygon's Exterior Ring.<br>");
+  html +=
+    wxT
+    ("The second input Geometry (if any) is expected to be a LINESTRING or MULTILINESTRING identifying any ");
+  html +=
+    wxT
+    ("polygon's Interior Ring (and all them are expected to be correctly closed).<br>");
+  html +=
+    wxT
+    ("<b><u>Please note well</u></b>: this function doesn't perform any internal topology check, so it could ");
+  html +=
+    wxT
+    ("possibly return an invalid polygon on invalid input.<hr>NULL will be returned if any error is encountered</td></tr>");
+  html +=
+    wxT
     ("<tr><td bgcolor=\"#fffff0\">LinesFromRings( geom Geometry ) : Geometry<hr>");
   html += wxT("ST_LinesFromRings( geom Geometry ) : Geometry</td>");
   html +=
@@ -9432,6 +11975,25 @@ void MyFrame::GetHelp(wxString & html)
     wxT
     ("<td bgcolor=\"#f0fff0\">return the max 3D-distance between geom1 and geom2 (considering Z coordinates)</td></tr>");
   html +=
+    wxT("<tr><td bgcolor=\"#fffff0\">ST_Node( geom Geometry ) : Geometry</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Fully nodes a set of linestrings using the least possible number of nodes while preserving all of the input ones.<br>");
+  html +=
+    wxT
+    ("NULL will be returned if the input Geometry isn't a set of linestrings or if any other error occurs.</td></tr>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">SelfIntersections( geom Geometry ) : Geometry<hr>ST_SelffIntersections( geom Geometry ) : Geometry</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Returns a MultiPoint Geometry representing any self-intersection found within the input geometry ");
+  html +=
+    wxT("[Expected to be of the Linestring or MultiLinestring type].<br>");
+  html +=
+    wxT
+    ("NULL will be returned for invalid arguments, or when no self-intersections were found.</td></tr>");
+  html +=
     wxT
     ("<tr><td bgcolor=\"#fffff0\">BuildMbr( x1 Double precision , y1 Double precision , x2 Double precision , y2 Double precision, [ , SRID Integer] ) : Geometry</td>");
   html +=
@@ -9473,7 +12035,6 @@ void MyFrame::GetHelp(wxString & html)
   html +=
     wxT
     ("<tr><td bgcolor=\"#fffff0\">MbrMinX( geom Geometry) : Double precision<hr>");
-  html += wxT("ST_MbrMinX( geom Geometry) : Double precision<hr>");
   html += wxT("ST_MinX( geom Geometry) : Double precision</td>");
   html +=
     wxT
@@ -9483,7 +12044,6 @@ void MyFrame::GetHelp(wxString & html)
   html +=
     wxT
     ("<tr><td bgcolor=\"#fffff0\">MbrMinY( geom Geometry) : Double precision<hr>");
-  html += wxT("ST_MbrMinY( geom Geometry) : Double precision<hr>");
   html += wxT("ST_MinY( geom Geometry) : Double precision</td>");
   html +=
     wxT
@@ -9493,7 +12053,6 @@ void MyFrame::GetHelp(wxString & html)
   html +=
     wxT
     ("<tr><td bgcolor=\"#fffff0\">MbrMaxX( geom Geometry) : Double precision<hr>");
-  html += wxT("ST_MbrMaxX( geom Geometry) : Double precision<hr>");
   html += wxT("ST_MaxX( geom Geometry) : Double precision</td>");
   html +=
     wxT
@@ -9503,7 +12062,6 @@ void MyFrame::GetHelp(wxString & html)
   html +=
     wxT
     ("<tr><td bgcolor=\"#fffff0\">MbrMaxY( geom Geometry) : Double precision<hr>");
-  html += wxT("ST_MbrMaxY( geom Geometry) : Double precision<hr>");
   html += wxT("ST_MaxY( geom Geometry) : Double precision</td>");
   html +=
     wxT
@@ -9892,7 +12450,7 @@ void MyFrame::GetHelp(wxString & html)
     ("Please note this SQL function open the doors to many potential security issues, and thus is always disabled by default.<br>");
   html +=
     wxT
-    ("Explicitly setting the environmente variable SPATIALITE_SECURITY=relaxed is absolutely required in order to effectively enable this function.</td></tr>");
+    ("Explicitly setting the environment variable SPATIALITE_SECURITY=relaxed is absolutely required in order to effectively enable this function.</td></tr>");
   html +=
     wxT
     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c34\">functions on type Geometry</a>");
@@ -10057,6 +12615,18 @@ void MyFrame::GetHelp(wxString & html)
     ("<td bgcolor=\"#f0fff0\">Replaces the Point into the input Linestring at \"position\" (zero-based index)<br>");
   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
   html +=
+    wxT("ST_SetStartPoint( line Linestring , point Point ) : Linestring</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Replaces the StartPoint into the input Linestring<br>");
+  html += wxT("NULL will be returned if any error is encountered.</td></tr>");
+  html +=
+    wxT("ST_SetEndtPoint( line Linestring , point Point ) : Linestring</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Replaces the EndPoint into the input Linestring<br>");
+  html += wxT("NULL will be returned if any error is encountered.</td></tr>");
+  html +=
     wxT
     ("<tr><td bgcolor=\"#fffff0\">RemovePoint( line Linestring , position Integer ) : Linestring<hr>");
   html +=
@@ -10953,7 +13523,7 @@ void MyFrame::GetHelp(wxString & html)
     ("<tr><td bgcolor=\"#fffff0\">RegisterVirtualGeometry( table String ) : Integer</td>");
   html +=
     wxT
-    ("<td bgcolor=\"#f0fff0\">Registers a VirtualShape table into Spatial MetaData tables; the VirtualShape table should be already created in some previous steo.<br>");
+    ("<td bgcolor=\"#f0fff0\">Registers a VirtualShape table into Spatial MetaData tables; the VirtualShape table should be already created in some previous step.<br>");
   html +=
     wxT
     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
@@ -10988,6 +13558,15 @@ void MyFrame::GetHelp(wxString & html)
     wxT
     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
   html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">CheckShadowedRowid( table String ) : Integer</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Checks if some table has a physical column named \"rowid\" (caseless) shadowing the real ROWID.<br>");
+  html +=
+    wxT
+    ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
+  html +=
     wxT("<tr><td bgcolor=\"#fffff0\">CheckSpatialIndex( void ) : Integer<hr>");
   html +=
     wxT("CheckSpatialIndex( table String , column String ) : Integer</td>");
@@ -11032,6 +13611,25 @@ void MyFrame::GetHelp(wxString & html)
     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
   html +=
     wxT
+    ("<tr><td bgcolor=\"#fffff0\">InvalidateLayerStatistics( void ) : Integer<hr>");
+  html +=
+    wxT
+    ("InvalidateLayerStatistics( table String [, column String ] ) : Integer</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Immediately and unconditionally invalidates the internal Layer Statistics<br>");
+  html +=
+    wxT
+    ("- if no arguments are passed, then internal statics will be invalidated for any possible Geometry Column ");
+  html += wxT("defined in the current DB<br>");
+  html +=
+    wxT
+    ("- otherwise statistics will be invalidated only for Geometry Columns corresponding to the given table<br>");
+  html +=
+    wxT
+    ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
+  html +=
+    wxT
     ("<tr><td bgcolor=\"#fffff0\">UpdateLayerStatistics( void ) : Integer<hr>");
   html +=
     wxT
@@ -11092,6 +13690,37 @@ void MyFrame::GetHelp(wxString & html)
     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE (failure).</td></tr>");
   html +=
     wxT
+    ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c43metacatalog\">functions for MetaCatalog and related Statistics</a>");
+  html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">CreateMetaCatalogTables( transaction Integer ) : Integer</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Creates both <b>splite_metacatalog</b> and <b>splite_metacatalog_statistics</b> tables; ");
+  html +=
+    wxT
+    ("<i>splite_metacatalog</i> will be populated so to describe every table/column currently defined within the DB.<br>");
+  html +=
+    wxT
+    ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE</td></tr>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">UpdateMetaCatalogTables( transaction Integer , table_name String, column_name String ) : Integer</hr>");
+  html +=
+    wxT
+    ("UpdateMetaCatalogTables( transaction Integer , master_table String , table_name String, column_name String ) : Integer</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Updates the <b>splite_metacatalog_statistics</b> table by computing the statistic summary for the required table/column.<br>");
+  html +=
+    wxT
+    ("the second form (four args) will use a MasterTable in order to identify all table/columns to be updated.<br>");
+  html +=
+    wxT
+    ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE</td></tr>");
+  html +=
+    wxT
     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c43style\">functions supporting SLD/SE Styled Layers</a>");
   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
   html +=
@@ -11103,8 +13732,7 @@ void MyFrame::GetHelp(wxString & html)
   html +=
     wxT
     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
-  html +=
-    wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
+  html += wxT("(failure): -1 will be returned on invalid arguments.</td></tr>");
   html +=
     wxT
     ("<tr><td bgcolor=\"#fffff0\">RegisterExternalGraphic( xlink_href String , resource BLOB ) : Integer<hr>");
@@ -11117,8 +13745,7 @@ void MyFrame::GetHelp(wxString & html)
   html +=
     wxT
     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
-  html +=
-    wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
+  html += wxT("(failure): -1 will be returned on invalid arguments.</td></tr>");
   html +=
     wxT
     ("<tr><td bgcolor=\"#fffff0\">RegisterVectorStyledLayer( f_table_name String , f_geometry_column String , style BLOB ) : Integer<hr>");
@@ -11131,8 +13758,7 @@ void MyFrame::GetHelp(wxString & html)
   html +=
     wxT
     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
-  html +=
-    wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
+  html += wxT("(failure): -1 will be returned on invalid arguments.</td></tr>");
   html +=
     wxT
     ("<tr><td bgcolor=\"#fffff0\">RegisterRasterStyledLayer( coverage_name String , style BLOB ) : Integer<hr>");
@@ -11145,22 +13771,20 @@ void MyFrame::GetHelp(wxString & html)
   html +=
     wxT
     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
-  html +=
-    wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
+  html += wxT("(failure): -1 will be returned on invalid arguments.</td></tr>");
   html +=
     wxT
-    ("<tr><td bgcolor=\"#fffff0\">RegisterStyledGroup( group_name String , f_table_name String , f_geometry_colum String , style_id Integer [ , paint_order Integer ] ) : Integer<hr>");
+    ("<tr><td bgcolor=\"#fffff0\">RegisterStyledGroup( group_name String , f_table_name String , f_geometry_colum String [ , paint_order Integer ] ) : Integer<hr>");
   html +=
     wxT
-    ("RegisterStyledGroup( group_name String, coverage_name String , style_id Integer [ , paint_order Integer ] ) : Integer</td>");
+    ("RegisterStyledGroup( group_name String, coverage_name String [ , paint_order Integer ] ) : Integer</td>");
   html +=
     wxT
     ("<td bgcolor=\"#f0fff0\">Inserts (or updates) a <b>Styled Group</b> definition.<br>");
   html +=
     wxT
     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
-  html +=
-    wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
+  html += wxT("(failure): -1 will be returned on invalid arguments.</td></tr>");
   html +=
     wxT
     ("<tr><td bgcolor=\"#fffff0\">SetStyledGroupInfos( group_name String , title String , abstract String ) : Integer</td>");
@@ -11170,8 +13794,20 @@ void MyFrame::GetHelp(wxString & html)
   html +=
     wxT
     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
+  html += wxT("(failure): -1 will be returned on invalid arguments.</td></tr>");
+  html +=
+    wxT
+    ("<tr><td bgcolor=\"#fffff0\">RegisterGroupStyle( group_name String , style BLOB ) : Integer<hr>");
   html +=
-    wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
+    wxT
+    ("RegisterGroupStyle( group_name String , style_id Integer , style BLOB ) : Integer</td>");
+  html +=
+    wxT
+    ("<td bgcolor=\"#f0fff0\">Inserts (or updates) a <b>Group Style</b> definition.<br>");
+  html +=
+    wxT
+    ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
+  html += wxT("(failure): -1 will be returned on invalid arguments.</td></tr>");
   html +=
     wxT
     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c43isometa\">functions implementing ISO Metadata</a>");
@@ -11185,8 +13821,7 @@ void MyFrame::GetHelp(wxString & html)
   html +=
     wxT
     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
-  html +=
-    wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
+  html += wxT("(failure): -1 will be returned on invalid arguments.</td></tr>");
   html +=
     wxT
     ("<tr><td bgcolor=\"#fffff0\">RegisterIsoMetadata( scope String , metadata BLOB ) : Integer<hr>");
@@ -11205,8 +13840,7 @@ void MyFrame::GetHelp(wxString & html)
   html +=
     wxT
     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
-  html +=
-    wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
+  html += wxT("(failure): -1 will be returned on invalid arguments.</td></tr>");
   html +=
     wxT
     ("<tr><td bgcolor=\"#fffff0\">GetIsoMetadataId( fileIdentifier String ) : Integer</td>");
@@ -11619,7 +14253,7 @@ void MyFrame::GetHelp(wxString & html)
     ("<u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always disabled by default.<br>");
   html +=
     wxT
-    ("Explicitly setting the environmente variable \"SPATIALITE_SECURITY=relaxed\" is absolutely required in order to effectively enable this function.<br>");
+    ("Explicitly setting the environment variable \"SPATIALITE_SECURITY=relaxed\" is absolutely required in order to effectively enable this function.<br>");
   html += wxT("Please see: CountUnsafeTriggers().</td></tr>");
   html +=
     wxT
@@ -11650,7 +14284,7 @@ void MyFrame::GetHelp(wxString & html)
     ("<u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always disabled by default.<br>");
   html +=
     wxT
-    ("Explicitly setting the environmente variable \"SPATIALITE_SECURITY=relaxed\" is absolutely required in order to effectively enable this function.<br>");
+    ("Explicitly setting the environment variable \"SPATIALITE_SECURITY=relaxed\" is absolutely required in order to effectively enable this function.<br>");
   html += wxT("Please see: CountUnsafeTriggers().</td></tr>");
   html += wxT("</table>");
   html += wxT("<a href=\"#index\">back to index</a>");
diff --git a/Makefile-static-Linux b/Makefile-static-Linux
index b790130..42c7264 100644
--- a/Makefile-static-Linux
+++ b/Makefile-static-Linux
@@ -20,7 +20,6 @@ EXTRALIBS = /usr/local/lib/libspatialite.a \
 	/usr/local/lib/libgeos_c.a /usr/local/lib/libgeos.a \
 	/usr/local/lib/libproj4.a \
 	/usr/local/lib/libfreexl.a \
-	/usr/local/lib/libgaiagraphics.a \
 	/usr/local/lib/libgeotiff.a \
 	/usr/local/lib/libpng.a /usr/local/lib/libz.a \
 	/usr/local/lib/libjpeg.a /usr/local/lib/libtiff.a
diff --git a/Makefile-static-MacOsX b/Makefile-static-MacOsX
index 8763937..c8c855f 100644
--- a/Makefile-static-MacOsX
+++ b/Makefile-static-MacOsX
@@ -18,14 +18,14 @@ EXTRAFLAGS = -Wall -Wextra -Wno-ctor-dtor-privacy \
 	-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1
 EXTRALIBS = /usr/local/lib/libspatialite.a /opt/local/lib/libgeos_c.a \
 	/opt/local/lib/libgeos.a /opt/local/lib/libproj.a  \
-	/usr/local/lib/libgaiagraphics.a /opt/local/lib/libgeotiff.a \
-        /opt/local/lib/libsqlite3.a /opt/local/lib/libcairo.a \
-        /opt/local/lib/libpixman-1.a /opt/local/lib/libfontconfig.a \
-        /opt/local/lib/libfreetype.a /opt/local/lib/libexpat.a \
+	/opt/local/lib/libgeotiff.a \
+	/opt/local/lib/libsqlite3.a /opt/local/lib/libcairo.a \
+	/opt/local/lib/libpixman-1.a /opt/local/lib/libfontconfig.a \
+	/opt/local/lib/libfreetype.a /opt/local/lib/libexpat.a \
 	/opt/local/lib/libtiff.a /opt/local/lib/libpng.a \
 	/opt/local/lib/libz.a /opt/local/lib/libjpeg.a \
 	/usr/local/lib/libfreexl.a \
-        /opt/local/lib/libcharset.a /opt/local/lib/libiconv.a
+	/opt/local/lib/libcharset.a /opt/local/lib/libiconv.a
 
 
 all: $(EXE)
diff --git a/Makefile-static-MinGW b/Makefile-static-MinGW
index 6446908..785caf8 100644
--- a/Makefile-static-MinGW
+++ b/Makefile-static-MinGW
@@ -4,38 +4,46 @@
 SRC = Main.cpp TableTree.cpp QueryView.cpp ResultSetView.cpp BlobExplorer.cpp \
 	Dialogs.cpp Shapefiles.cpp Network.cpp Exif.cpp TextCsv.cpp \
 	Objects.cpp QueryViewComposer.cpp MalformedGeoms.cpp DialogsGraph.cpp \
-	Wfs.cpp win_resource/resource.rc
+	Raster.cpp Styles.cpp RasterSymbolizers.cpp VectorSymbolizers1.cpp \
+	VectorSymbolizers2.cpp Wfs.cpp win_resource/resource.rc
 OBJ = Main.o TableTree.o QueryView.o ResultSetView.o BlobExplorer.o \
 	Dialogs.o Shapefiles.o Network.o Exif.o TextCsv.o Objects.o \
 	QueryViewComposer.o MalformedGeoms.o DialogsGraph.o \
-	Wfs.o win_resource/resource.o 
+	Raster.o Styles.o RasterSymbolizers.o VectorSymbolizers1.o \
+	VectorSymbolizers2.o Wfs.o win_resource/resource.o 
 EXE = ./static_bin/spatialite_gui.exe
 INCLUDE = Classdef.h 
 
 # Define default flags:
 CXXFLAGS = $(shell wx-config --cxxflags)
-LIB = $(shell wx-config --libs)
+LIB = -Wl,--subsystem,windows /usr/local/lib/libwx_mswu-3.0.a \
+	-lrpcrt4 -loleaut32 -lole32 -luuid -lwinspool -lwinmm -lshell32 \
+	-lcomctl32 -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32
 EXTRAFLAGS = -Wall -Wextra -Wno-ctor-dtor-privacy \
 	-fno-strict-aliasing -I/usr/local/include -D_LARGE_FILE=1 \
 	-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1
 REZ = $(shell wx-config --rescomp)
-EXTRALIBS = /usr/local/lib/libspatialite.a /usr/local/lib/libxml2.a \
-	/usr/local/lib/liblwgeom.a /usr/local/lib/libgeos_c.a \
-	/usr/local/lib/libiconv.a /usr/local/lib/libgeos.a \
-	/usr/local/lib/libproj.a /usr/local/lib/libgaiagraphics.a \
+EXTRALIBS = /usr/local/lib/librasterlite2.a /usr/local/lib/libspatialite.a \
+	/usr/local/lib/libxml2.a /usr/local/lib/liblwgeom.a \
+	/usr/local/lib/libgeos_c.a /usr/local/lib/libiconv.a \
+	/usr/local/lib/libgeos.a /usr/local/lib/libproj.a \
 	/usr/local/lib/libcairo.a /usr/local/lib/libpixman-1.a \
 	/usr/local/lib/libfreexl.a /usr/local/lib/libfontconfig.a \
 	/usr/local/lib/libfreetype.a /usr/local/lib/libexpat.a \
 	/usr/local/lib/libgeotiff.a /usr/local/lib/libtiff.a \
-	/usr/local/lib/libpng.a /usr/local/lib/libz.a \
-	/usr/local/lib/liblzma.a /usr/local/lib/libjpeg.a \
-	/usr/local/lib/libsqlite3.a
-EXTRALIB2 = -lmsimg32 -lws2_32
+	/usr/local/lib/libpng.a /usr/local/lib/libjpeg.a \
+	/usr/local/lib/libsqlite3.a /usr/local/lib/libcurl.a \
+	/usr/local/lib/libwebp.a /usr/local/lib/libgif.a \
+	/usr/local/lib/libssl.a /usr/local/lib/libcrypto.a \
+	/usr/local/lib/libz.a /usr/local/lib/liblzma.a \
+	/usr/local/lib/libCharLS.a /usr/local/lib/libopenjp2.a
+EXTRALIB2 = -lmsimg32 -lws2_32 -lwldap32
+
 
 all: $(EXE)
 
 $(EXE): $(OBJ) $(EXTRALIBS)
-	$(CXX) $(OBJ) -o $(EXE) $(LIB) $(EXTRALIBS) $(EXTRALIB2) \
+	$(CXX) $(OBJ) -o $(EXE) $(EXTRALIBS) $(EXTRALIB2) $(LIB) \
 	-static-libstdc++ -static-libgcc
 	strip --strip-all  $(EXE)
 
@@ -60,6 +68,21 @@ BlobExplorer.o: BlobExplorer.cpp $(INCLUDE)
 Dialogs.o: Dialogs.cpp $(INCLUDE)
 	$(CXX) -c Dialogs.cpp $(CXXFLAGS) $(EXTRAFLAGS)
 
+Raster.o: Raster.cpp $(INCLUDE)
+	$(CXX) -c Raster.cpp $(CXXFLAGS) $(EXTRAFLAGS)
+
+Styles.o: Styles.cpp $(INCLUDE)
+	$(CXX) -c Styles.cpp $(CXXFLAGS) $(EXTRAFLAGS)
+
+RasterSymbolizers.o: RasterSymbolizers.cpp $(INCLUDE)
+	$(CXX) -c RasterSymbolizers.cpp $(CXXFLAGS) $(EXTRAFLAGS)
+
+VectorSymbolizers1.o: VectorSymbolizers1.cpp $(INCLUDE)
+	$(CXX) -c VectorSymbolizers1.cpp $(CXXFLAGS) $(EXTRAFLAGS)
+
+VectorSymbolizers2.o: VectorSymbolizers2.cpp $(INCLUDE)
+	$(CXX) -c VectorSymbolizers2.cpp $(CXXFLAGS) $(EXTRAFLAGS)
+
 DialogsGraph.o: DialogsGraph.cpp $(INCLUDE)
 	$(CXX) -c DialogsGraph.cpp $(CXXFLAGS) $(EXTRAFLAGS)
 
diff --git a/Makefile.am b/Makefile.am
index d72f483..70e4ce2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,23 +2,25 @@ ACLOCAL_AMFLAGS = -I m4
 
 bin_PROGRAMS = spatialite_gui
 
-INCLUDES = @CFLAGS@
-INCLUDES += -I$(top_srcdir)
+AM_CPPFLAGS = @CFLAGS@
+AM_CPPFLAGS += -I$(top_srcdir)
 
 spatialite_gui_SOURCES = Classdef.h BlobExplorer.cpp \
 	Dialogs.cpp DialogsGraph.cpp Exif.cpp \
 	Main.cpp MalformedGeoms.cpp Network.cpp \
 	Objects.cpp QueryView.cpp QueryViewComposer.cpp \
 	ResultSetView.cpp Shapefiles.cpp TableTree.cpp \
-	TextCsv.cpp Wfs.cpp
+	TextCsv.cpp Wfs.cpp Raster.cpp Styles.cpp \
+	RasterSymbolizers.cpp VectorSymbolizers1.cpp \
+	VectorSymbolizers2.cpp
 
-LDADD = @WX_LIBS@ @LIBGAIAGRAPHICS_LIBS@ @LIBSPATIALITE_LIBS@ \
-	@LIBFREEXL_LIBS@ @LIBXML2_LIBS@
+LDADD = @WX_LIBS@ @LIBSPATIALITE_LIBS@ \
+	@LIBRASTERLITE2_LIBS@ @LIBFREEXL_LIBS@ @LIBXML2_LIBS@
 
 EXTRA_DIST = Makefile-static-MinGW \
         Makefile-static-Linux \
         Makefile-static-MacOsX \
-	indent_me
+        indent_me
 
 AUTOMAKE_OPTIONS = dist-zip
 
diff --git a/Makefile.in b/Makefile.in
index c9515bd..1b6f75f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.12.2 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2012 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -15,23 +15,61 @@
 @SET_MAKE@
 
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \	]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -52,10 +90,6 @@ build_triplet = @build@
 host_triplet = @host@
 bin_PROGRAMS = spatialite_gui$(EXEEXT)
 subdir = .
-DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
-	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
-	$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
-	config.guess config.sub depcomp install-sh ltmain.sh missing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -63,6 +97,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+	$(am__configure_deps) $(am__DIST_COMMON)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno config.status.lineno
 mkinstalldirs = $(install_sh) -d
@@ -76,41 +112,78 @@ am_spatialite_gui_OBJECTS = BlobExplorer.$(OBJEXT) Dialogs.$(OBJEXT) \
 	MalformedGeoms.$(OBJEXT) Network.$(OBJEXT) Objects.$(OBJEXT) \
 	QueryView.$(OBJEXT) QueryViewComposer.$(OBJEXT) \
 	ResultSetView.$(OBJEXT) Shapefiles.$(OBJEXT) \
-	TableTree.$(OBJEXT) TextCsv.$(OBJEXT) Wfs.$(OBJEXT)
+	TableTree.$(OBJEXT) TextCsv.$(OBJEXT) Wfs.$(OBJEXT) \
+	Raster.$(OBJEXT) Styles.$(OBJEXT) RasterSymbolizers.$(OBJEXT) \
+	VectorSymbolizers1.$(OBJEXT) VectorSymbolizers2.$(OBJEXT)
 spatialite_gui_OBJECTS = $(am_spatialite_gui_OBJECTS)
 spatialite_gui_LDADD = $(LDADD)
 spatialite_gui_DEPENDENCIES =
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
 DEFAULT_INCLUDES = -I. at am__isrc@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
 	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-	--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
 CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-	--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
-	$(LDFLAGS) -o $@
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
 CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
-	$(LDFLAGS) -o $@
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
 SOURCES = $(spatialite_gui_SOURCES)
 DIST_SOURCES = $(spatialite_gui_SOURCES)
-RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
-	html-recursive info-recursive install-data-recursive \
-	install-dvi-recursive install-exec-recursive \
-	install-html-recursive install-info-recursive \
-	install-pdf-recursive install-ps-recursive install-recursive \
-	installcheck-recursive installdirs-recursive pdf-recursive \
-	ps-recursive uninstall-recursive
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -118,13 +191,37 @@ am__can_run_installinfo = \
   esac
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
   distclean-recursive maintainer-clean-recursive
-AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
-	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
 	cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+	$(LISP)config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
 CSCOPE = cscope
 DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \
+	COPYING ChangeLog INSTALL NEWS README compile config.guess \
+	config.sub depcomp install-sh ltmain.sh missing
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -169,6 +266,7 @@ am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
 distcleancheck_listfiles = find . -type f -print
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -209,13 +307,17 @@ LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBFREEXL_CFLAGS = @LIBFREEXL_CFLAGS@
 LIBFREEXL_LIBS = @LIBFREEXL_LIBS@
-LIBGAIAGRAPHICS_CFLAGS = @LIBGAIAGRAPHICS_CFLAGS@
-LIBGAIAGRAPHICS_LIBS = @LIBGAIAGRAPHICS_LIBS@
+LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
+LIBLZMA_LIBS = @LIBLZMA_LIBS@
 LIBOBJS = @LIBOBJS@
+LIBRASTERLITE2_CFLAGS = @LIBRASTERLITE2_CFLAGS@
+LIBRASTERLITE2_LIBS = @LIBRASTERLITE2_LIBS@
 LIBS = @LIBS@
 LIBSPATIALITE_CFLAGS = @LIBSPATIALITE_CFLAGS@
 LIBSPATIALITE_LIBS = @LIBSPATIALITE_LIBS@
 LIBTOOL = @LIBTOOL@
+LIBWEBP_CFLAGS = @LIBWEBP_CFLAGS@
+LIBWEBP_LIBS = @LIBWEBP_LIBS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -249,7 +351,7 @@ SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 VERSION = @VERSION@
-WX_CONFIG = @WX_CONFIG@
+WXCONFIG = @WXCONFIG@
 WX_LIBS = @WX_LIBS@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
@@ -305,21 +407,23 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 ACLOCAL_AMFLAGS = -I m4
-INCLUDES = @CFLAGS@ -I$(top_srcdir)
+AM_CPPFLAGS = @CFLAGS@ -I$(top_srcdir)
 spatialite_gui_SOURCES = Classdef.h BlobExplorer.cpp \
 	Dialogs.cpp DialogsGraph.cpp Exif.cpp \
 	Main.cpp MalformedGeoms.cpp Network.cpp \
 	Objects.cpp QueryView.cpp QueryViewComposer.cpp \
 	ResultSetView.cpp Shapefiles.cpp TableTree.cpp \
-	TextCsv.cpp Wfs.cpp
+	TextCsv.cpp Wfs.cpp Raster.cpp Styles.cpp \
+	RasterSymbolizers.cpp VectorSymbolizers1.cpp \
+	VectorSymbolizers2.cpp
 
-LDADD = @WX_LIBS@ @LIBGAIAGRAPHICS_LIBS@ @LIBSPATIALITE_LIBS@ \
-	@LIBFREEXL_LIBS@ @LIBXML2_LIBS@
+LDADD = @WX_LIBS@ @LIBSPATIALITE_LIBS@ \
+	@LIBRASTERLITE2_LIBS@ @LIBFREEXL_LIBS@ @LIBXML2_LIBS@
 
 EXTRA_DIST = Makefile-static-MinGW \
         Makefile-static-Linux \
         Makefile-static-MacOsX \
-	indent_me
+        indent_me
 
 AUTOMAKE_OPTIONS = dist-zip
 SUBDIRS = icons win_resource mac_resource gnome_resource
@@ -343,7 +447,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -364,8 +467,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
 $(am__aclocal_m4_deps):
 
 config.h: stamp-h1
-	@if test ! -f $@; then rm -f stamp-h1; else :; fi
-	@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
+	@test -f $@ || rm -f stamp-h1
+	@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
 
 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
 	@rm -f stamp-h1
@@ -386,10 +489,12 @@ install-binPROGRAMS: $(bin_PROGRAMS)
 	fi; \
 	for p in $$list; do echo "$$p $$p"; done | \
 	sed 's/$(EXEEXT)$$//' | \
-	while read p p1; do if test -f $$p || test -f $$p1; \
-	  then echo "$$p"; echo "$$p"; else :; fi; \
+	while read p p1; do if test -f $$p \
+	 || test -f $$p1 \
+	  ; then echo "$$p"; echo "$$p"; else :; fi; \
 	done | \
-	sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+	sed -e 'p;s,.*/,,;n;h' \
+	    -e 's|.*|.|' \
 	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
 	sed 'N;N;N;s,\n, ,g' | \
 	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
@@ -410,7 +515,8 @@ uninstall-binPROGRAMS:
 	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
 	files=`for p in $$list; do echo "$$p"; done | \
 	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-	      -e 's/$$/$(EXEEXT)/' `; \
+	      -e 's/$$/$(EXEEXT)/' \
+	`; \
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
 	cd "$(DESTDIR)$(bindir)" && rm -f $$files
@@ -423,9 +529,10 @@ clean-binPROGRAMS:
 	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
 	echo " rm -f" $$list; \
 	rm -f $$list
+
 spatialite_gui$(EXEEXT): $(spatialite_gui_OBJECTS) $(spatialite_gui_DEPENDENCIES) $(EXTRA_spatialite_gui_DEPENDENCIES) 
 	@rm -f spatialite_gui$(EXEEXT)
-	$(CXXLINK) $(spatialite_gui_OBJECTS) $(spatialite_gui_LDADD) $(LIBS)
+	$(AM_V_CXXLD)$(CXXLINK) $(spatialite_gui_OBJECTS) $(spatialite_gui_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -443,32 +550,37 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Objects.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/QueryView.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/QueryViewComposer.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Raster.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/RasterSymbolizers.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ResultSetView.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Shapefiles.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Styles.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TableTree.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TextCsv.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/VectorSymbolizers1.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/VectorSymbolizers2.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Wfs.Po at am__quote@
 
 .cpp.o:
- at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
- at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
 
 .cpp.obj:
- at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
- at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .cpp.lo:
- at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
- at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
 
 mostlyclean-libtool:
 	-rm -f *.lo
@@ -485,14 +597,13 @@ distclean-libtool:
 # (1) if the variable is set in 'config.status', edit 'config.status'
 #     (which will cause the Makefiles to be regenerated when you run 'make');
 # (2) otherwise, pass the desired values on the 'make' command line.
-$(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS):
-	@fail= failcom='exit 1'; \
-	for f in x $$MAKEFLAGS; do \
-	  case $$f in \
-	    *=* | --[!k]*);; \
-	    *k*) failcom='fail=yes';; \
-	  esac; \
-	done; \
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
 	dot_seen=no; \
 	target=`echo $@ | sed s/-recursive//`; \
 	case "$@" in \
@@ -513,31 +624,13 @@ $(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS):
 	if test "$$dot_seen" = "no"; then \
 	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
 	fi; test -z "$$fail"
-tags-recursive:
-	list='$(SUBDIRS)'; for subdir in $$list; do \
-	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
-	done
-ctags-recursive:
-	list='$(SUBDIRS)'; for subdir in $$list; do \
-	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
-	done
-cscopelist-recursive:
-	list='$(SUBDIRS)'; for subdir in $$list; do \
-	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \
-	done
 
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	mkid -fID $$unique
-tags: TAGS
-
-TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
 	set x; \
 	here=`pwd`; \
 	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
@@ -553,12 +646,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
 	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
 	  fi; \
 	done; \
-	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	$(am__define_uniq_tagged_files); \
 	shift; \
 	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
 	  test -n "$$unique" || unique=$$empty_fix; \
@@ -570,15 +658,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
 	      $$unique; \
 	  fi; \
 	fi
-ctags: CTAGS
-CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
 	test -z "$(CTAGS_ARGS)$$unique" \
 	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
 	     $$unique
@@ -587,18 +671,16 @@ GTAGS:
 	here=`$(am__cd) $(top_builddir) && pwd` \
 	  && $(am__cd) $(top_srcdir) \
 	  && gtags -i $(GTAGS_ARGS) "$$here"
-
 cscope: cscope.files
 	test ! -s cscope.files \
 	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
-
 clean-cscope:
 	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
 
-cscope.files: clean-cscope cscopelist-recursive cscopelist
-
-cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP)
-	list='$(SOURCES) $(HEADERS) $(LISP)'; \
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
 	case "$(srcdir)" in \
 	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
 	  *) sdir=$(subdir)/$(srcdir) ;; \
@@ -696,10 +778,16 @@ dist-xz: distdir
 	$(am__post_remove_distdir)
 
 dist-tarZ: distdir
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
 	$(am__post_remove_distdir)
 
 dist-shar: distdir
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
 	$(am__post_remove_distdir)
 dist-zip: distdir
@@ -731,18 +819,19 @@ distcheck: dist
 	*.zip*) \
 	  unzip $(distdir).zip ;;\
 	esac
-	chmod -R a-w $(distdir); chmod u+w $(distdir)
-	mkdir $(distdir)/_build
-	mkdir $(distdir)/_inst
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
 	chmod a-w $(distdir)
 	test -d $(distdir)/_build || exit 0; \
 	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
 	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
 	  && am__cwd=`pwd` \
-	  && $(am__cd) $(distdir)/_build \
-	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	  && $(am__cd) $(distdir)/_build/sub \
+	  && ../../configure \
 	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
 	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	    --srcdir=../.. --prefix="$$dc_install_base" \
 	  && $(MAKE) $(AM_MAKEFLAGS) \
 	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
 	  && $(MAKE) $(AM_MAKEFLAGS) check \
@@ -906,28 +995,27 @@ ps-am:
 
 uninstall-am: uninstall-binPROGRAMS
 
-.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
-	cscopelist-recursive ctags-recursive install-am install-strip \
-	tags-recursive
-
-.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
-	all all-am am--refresh check check-am clean clean-binPROGRAMS \
-	clean-cscope clean-generic clean-libtool cscope cscopelist \
-	cscopelist-recursive ctags ctags-recursive dist dist-all \
-	dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ dist-xz \
-	dist-zip distcheck distclean distclean-compile \
-	distclean-generic distclean-hdr distclean-libtool \
-	distclean-tags distcleancheck distdir distuninstallcheck dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-binPROGRAMS install-data install-data-am install-dvi \
-	install-dvi-am install-exec install-exec-am install-html \
-	install-html-am install-info install-info-am install-man \
-	install-pdf install-pdf-am install-ps install-ps-am \
-	install-strip installcheck installcheck-am installdirs \
-	installdirs-am maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
-	uninstall uninstall-am uninstall-binPROGRAMS
+.MAKE: $(am__recursive_targets) all install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+	am--refresh check check-am clean clean-binPROGRAMS \
+	clean-cscope clean-generic clean-libtool cscope cscopelist-am \
+	ctags ctags-am dist dist-all dist-bzip2 dist-gzip dist-lzip \
+	dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \
+	distclean-compile distclean-generic distclean-hdr \
+	distclean-libtool distclean-tags distcleancheck distdir \
+	distuninstallcheck dvi dvi-am html html-am info info-am \
+	install install-am install-binPROGRAMS install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-binPROGRAMS
+
+.PRECIOUS: Makefile
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/MalformedGeoms.cpp b/MalformedGeoms.cpp
index 257004a..98c88b0 100644
--- a/MalformedGeoms.cpp
+++ b/MalformedGeoms.cpp
@@ -470,19 +470,22 @@ MalformedGeomsList *MyFrame::FindMalformedGeoms(wxString & table,
               if (not_a_line == false && not_a_ring == false
                   && unclosed_ring == false)
                 {
-                  if (!gaiaIsValid(geom))
+                  if (!gaiaIsValid_r(GetSpliteInternalCache(), geom))
                     {
                       wxString geos_error =
-                        wxString::FromUTF8(gaiaGetGeosErrorMsg());
+                        wxString::FromUTF8(gaiaGetGeosErrorMsg_r
+                                           (GetSpliteInternalCache()));
                       if (geos_error.Len() == 0)
                         geos_error =
-                          wxString::FromUTF8(gaiaGetGeosWarningMsg());
+                          wxString::FromUTF8(gaiaGetGeosWarningMsg_r
+                                             (GetSpliteInternalCache()));
                       msg = wxT("GEOS invalid Geometry");
                       list->AddEntity(int_value, 1, false, msg, geos_error);
                   } else
                     {
                       wxString geos_warning =
-                        wxString::FromUTF8(gaiaGetGeosWarningMsg());
+                        wxString::FromUTF8(gaiaGetGeosWarningMsg_r
+                                           (GetSpliteInternalCache()));
                       if (geos_warning.Len() > 0)
                         {
                           msg = wxT("GEOS warning");
@@ -757,26 +760,26 @@ void MalformedGeomsDialog::OnRightClick(wxGridEvent & event)
 //
 // right click on some cell [mouse action]
 //
-  wxMenu *menu = new wxMenu();
+  wxMenu menu;
   wxMenuItem *menuItem;
   wxPoint pt = event.GetPosition();
   CurrentEvtRow = event.GetRow();
   CurrentEvtColumn = event.GetCol();
-  menuItem = new wxMenuItem(menu, ID_MALFORMED_BLOB, wxT("BLOB &explore"));
-  menu->Append(menuItem);
-  menu->AppendSeparator();
-  menuItem = new wxMenuItem(menu, ID_MALFORMED_CLEAR, wxT("&Clear selection"));
-  menu->Append(menuItem);
-  menuItem = new wxMenuItem(menu, ID_MALFORMED_ALL, wxT("Select &all"));
-  menu->Append(menuItem);
-  menuItem = new wxMenuItem(menu, ID_MALFORMED_ROW, wxT("Select &row"));
-  menu->Append(menuItem);
-  menuItem = new wxMenuItem(menu, ID_MALFORMED_COLUMN, wxT("&Select column"));
-  menu->Append(menuItem);
-  menu->AppendSeparator();
-  menuItem = new wxMenuItem(menu, ID_MALFORMED_COPY, wxT("&Copy"));
-  menu->Append(menuItem);
-  GridCtrl->PopupMenu(menu, pt);
+  menuItem = new wxMenuItem(&menu, ID_MALFORMED_BLOB, wxT("BLOB &explore"));
+  menu.Append(menuItem);
+  menu.AppendSeparator();
+  menuItem = new wxMenuItem(&menu, ID_MALFORMED_CLEAR, wxT("&Clear selection"));
+  menu.Append(menuItem);
+  menuItem = new wxMenuItem(&menu, ID_MALFORMED_ALL, wxT("Select &all"));
+  menu.Append(menuItem);
+  menuItem = new wxMenuItem(&menu, ID_MALFORMED_ROW, wxT("Select &row"));
+  menu.Append(menuItem);
+  menuItem = new wxMenuItem(&menu, ID_MALFORMED_COLUMN, wxT("&Select column"));
+  menu.Append(menuItem);
+  menu.AppendSeparator();
+  menuItem = new wxMenuItem(&menu, ID_MALFORMED_COPY, wxT("&Copy"));
+  menu.Append(menuItem);
+  GridCtrl->PopupMenu(&menu, pt);
 }
 
 void MalformedGeomsDialog::OnCmdBlob(wxCommandEvent & WXUNUSED(event))
@@ -1529,23 +1532,23 @@ void DbStatusDialog::OnRightClick(wxGridEvent & event)
 //
 // right click on some cell [mouse action]
 //
-  wxMenu *menu = new wxMenu();
+  wxMenu menu;
   wxMenuItem *menuItem;
   wxPoint pt = event.GetPosition();
   CurrentEvtRow = event.GetRow();
   CurrentEvtColumn = event.GetCol();
-  menuItem = new wxMenuItem(menu, ID_DB_STATUS_CLEAR, wxT("&Clear selection"));
-  menu->Append(menuItem);
-  menuItem = new wxMenuItem(menu, ID_DB_STATUS_ALL, wxT("Select &all"));
-  menu->Append(menuItem);
-  menuItem = new wxMenuItem(menu, ID_DB_STATUS_ROW, wxT("Select &row"));
-  menu->Append(menuItem);
-  menuItem = new wxMenuItem(menu, ID_DB_STATUS_COLUMN, wxT("&Select column"));
-  menu->Append(menuItem);
-  menu->AppendSeparator();
-  menuItem = new wxMenuItem(menu, ID_DB_STATUS_COPY, wxT("&Copy"));
-  menu->Append(menuItem);
-  GridCtrl->PopupMenu(menu, pt);
+  menuItem = new wxMenuItem(&menu, ID_DB_STATUS_CLEAR, wxT("&Clear selection"));
+  menu.Append(menuItem);
+  menuItem = new wxMenuItem(&menu, ID_DB_STATUS_ALL, wxT("Select &all"));
+  menu.Append(menuItem);
+  menuItem = new wxMenuItem(&menu, ID_DB_STATUS_ROW, wxT("Select &row"));
+  menu.Append(menuItem);
+  menuItem = new wxMenuItem(&menu, ID_DB_STATUS_COLUMN, wxT("&Select column"));
+  menu.Append(menuItem);
+  menu.AppendSeparator();
+  menuItem = new wxMenuItem(&menu, ID_DB_STATUS_COPY, wxT("&Copy"));
+  menu.Append(menuItem);
+  GridCtrl->PopupMenu(&menu, pt);
 }
 
 void DbStatusDialog::OnCmdClearSelection(wxCommandEvent & WXUNUSED(event))
diff --git a/Network.cpp b/Network.cpp
index 81b3e71..360f666 100644
--- a/Network.cpp
+++ b/Network.cpp
@@ -34,10 +34,11 @@
 
 void
   MyFrame::BuildNetwork(wxString & table, wxString & from, wxString & to,
-                        wxString & geometry, wxString & name, bool cost_length,
-                        wxString & cost, bool bidirectional, bool one_way,
-                        wxString & one_way_from_to, wxString & one_way_to_from,
-                        bool aStarSupported)
+                        bool isNoGeometry, wxString & geometry, wxString & name,
+                        bool cost_length, wxString & cost, bool bidirectional,
+                        bool one_way, wxString & one_way_from_to,
+                        wxString & one_way_to_from, bool aStarSupported,
+                        wxString & dataTableName, wxString & virtualTableName)
 {
 //
 // trying to build a Network
@@ -107,6 +108,15 @@ void
   double a_star_coeff;
   double min_a_star_coeff = DBL_MAX;
   char xname[1024];
+
+  if (isNoGeometry == true)
+    {
+      BuildNetwork(table, from, to, name, cost, bidirectional, one_way,
+                   one_way_from_to, one_way_to_from, dataTableName,
+                   virtualTableName);
+      return;
+    }
+
   ::wxBeginBusyCursor();
 // checking for table existence
   sql =
@@ -266,7 +276,7 @@ void
           if (type == SQLITE_INTEGER)
             {
               from_int = true;
-              id_from = sqlite3_column_int(stmt, 0);
+              id_from = sqlite3_column_int64(stmt, 0);
               p_graph->InsertNode(id_from);
             }
           if (type == SQLITE_FLOAT)
@@ -286,7 +296,7 @@ void
           if (type == SQLITE_INTEGER)
             {
               to_int = true;
-              id_to = sqlite3_column_int(stmt, 1);
+              id_to = sqlite3_column_int64(stmt, 1);
               p_graph->InsertNode(id_to);
             }
           if (type == SQLITE_FLOAT)
@@ -445,7 +455,7 @@ void
           strcpy(xname, geometry.ToUTF8());
           DoubleQuotedSql(xname);
           sql += wxT(", GLength(") + wxString::FromUTF8(xname) + wxT(")");
-          col_n = 8;
+          col_n = 9;
           aStarLength = false;
           min_a_star_coeff = 1.0;
         }
@@ -457,13 +467,14 @@ void
           strcpy(xname, cost.ToUTF8());
           DoubleQuotedSql(xname);
           sql += wxT(", ") + wxString::FromUTF8(xname);
+          col_n = 8;
       } else
         {
           strcpy(xname, geometry.ToUTF8());
           DoubleQuotedSql(xname);
           sql += wxT(", GLength(") + wxString::FromUTF8(xname) + wxT(")");
+          col_n = 9;
         }
-      col_n = 8;
       aStarLength = false;
     }
   if (one_way == true)
@@ -549,13 +560,6 @@ void
               if (a_star_coeff < min_a_star_coeff)
                 min_a_star_coeff = a_star_coeff;
             }
-          if (one_way == true)
-            {
-              // fetching the OneWay-FromTo value
-              fromto = sqlite3_column_int(stmt, fromto_n);
-              // fetching the OneWay-ToFrom value
-              tofrom = sqlite3_column_int(stmt, tofrom_n);
-            }
           if (bidirectional == true)
             {
               if (fromto)
@@ -593,7 +597,870 @@ void
               sqlite3_finalize(stmt);
               goto abort;
             }
-      } else
+      } else
+        {
+          wxString err = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
+          wxMessageBox(wxT("sqlite3_step error: ") + err, wxT("spatialite_gui"),
+                       wxOK | wxICON_ERROR, this);
+          sqlite3_finalize(stmt);
+          goto abort;
+        }
+    }
+  sqlite3_finalize(stmt);
+  ::wxEndBusyCursor();
+  wr =
+    CreateNetwork(p_graph, table, from, to, geometry, name,
+                  aStarSupported, min_a_star_coeff, dataTableName,
+                  virtualTableName);
+  if (wr == true)
+    {
+      endMsg =
+        wxT("OK: VirtualNetwork table '") + table +
+        wxT("_net' successfully created");
+      wxMessageBox(endMsg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
+                   this);
+  } else
+    {
+      endMsg =
+        wxT("DB ERROR: VirtualNetwork table '") + table +
+        wxT("_net' was not created");
+      wxMessageBox(endMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+    }
+  if (p_graph)
+    delete p_graph;
+  InitTableTree();
+  return;
+abort:
+  ::wxEndBusyCursor();
+  msg =
+    wxT
+    ("It's impossible to build a Network using the given configuration;\nsome fatal error occurred\n\n");
+  msg += wxT("please note: using the 'spatialite_network' command-line tool\n");
+  msg +=
+    wxT
+    ("you can obtain a full detailed report explaining causes for this failure");
+  wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+  if (p_graph)
+    delete p_graph;
+}
+
+void
+  MyFrame::BuildNetwork(wxString & table, wxString & from, wxString & to,
+                        wxString & name, wxString & cost, bool bidirectional,
+                        bool one_way, wxString & one_way_from_to,
+                        wxString & one_way_to_from, wxString & dataTableName,
+                        wxString & virtualTableName)
+{
+//
+// trying to build a Network - NO-GEOMETRY
+// 
+  int ret;
+  sqlite3_stmt *stmt;
+  Network *p_graph = NULL;
+  wxString sql;
+  char xsql[2048];
+  char **results;
+  int n_rows;
+  int n_columns;
+  int i;
+  char *errMsg = NULL;
+  char *col_name;
+  int type;
+  bool ok_from_column = false;
+  bool ok_to_column = false;
+  bool ok_cost_column = false;
+  bool ok_name_column = false;
+  bool ok_oneway_tofrom = false;
+  bool ok_oneway_fromto = false;
+  bool from_null = false;
+  bool from_int = false;
+  bool from_double = false;
+  bool from_text = false;
+  bool from_blob = false;
+  bool to_null = false;
+  bool to_int = false;
+  bool to_double = false;
+  bool to_text = false;
+  bool to_blob = false;
+  bool cost_null = false;
+  bool cost_text = false;
+  bool cost_blob = false;
+  bool tofrom_null = false;
+  bool tofrom_double = false;
+  bool tofrom_text = false;
+  bool tofrom_blob = false;
+  bool fromto_null = false;
+  bool fromto_double = false;
+  bool fromto_text = false;
+  bool fromto_blob = false;
+  int col_n;
+  int fromto_n = 0;
+  int tofrom_n = 0;
+  sqlite3_int64 rowid;
+  sqlite3_int64 id_from = -1;
+  sqlite3_int64 id_to = -1;
+  char code_from[1024];
+  char code_to[1024];
+  double cost_val;
+  int fromto;
+  int tofrom;
+  wxString endMsg;
+  wxString msg;
+  bool wr;
+  char xname[1024];
+
+  ::wxBeginBusyCursor();
+// checking for table existence
+  sql =
+    wxT("SELECT tbl_name FROM sqlite_master WHERE Lower(tbl_name) = Lower('");
+  strcpy(xname, table.ToUTF8());
+  CleanSqlString(xname);
+  sql += wxString::FromUTF8(xname);
+  sql += wxT("') AND type = 'table'");
+  strcpy(xsql, sql.ToUTF8());
+  ret =
+    sqlite3_get_table(SqliteHandle, xsql, &results, &n_rows, &n_columns,
+                      &errMsg);
+  if (ret != SQLITE_OK)
+    {
+// some error occurred 
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      goto abort;
+    }
+  if (n_rows == 0)
+    {
+      // required table does not exists 
+      wxMessageBox(wxT("ERROR: table ") + table + wxT(" does not exists"),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      goto abort;
+  } else
+    sqlite3_free_table(results);
+// checking for columns existence
+  sql = wxT("PRAGMA table_info(");
+  strcpy(xname, table.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql += wxString::FromUTF8(xname);
+  sql += wxT(")");
+  strcpy(xsql, sql.ToUTF8());
+  ret =
+    sqlite3_get_table(SqliteHandle, xsql, &results, &n_rows, &n_columns,
+                      &errMsg);
+  if (ret != SQLITE_OK)
+    {
+// some error occurred 
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      goto abort;
+    }
+  if (n_rows > 1)
+    {
+      for (i = 1; i <= n_rows; i++)
+        {
+          char xcol[256];
+          col_name = results[(i * n_columns) + 1];
+          strcpy(xcol, from.ToUTF8());
+          if (strcasecmp(xcol, col_name) == 0)
+            ok_from_column = true;
+          strcpy(xcol, to.ToUTF8());
+          if (strcasecmp(xcol, col_name) == 0)
+            ok_to_column = true;
+          strcpy(xcol, cost.ToUTF8());
+          if (strcasecmp(xcol, col_name) == 0)
+            ok_cost_column = true;
+          if (name.Len() > 0)
+            {
+              strcpy(xcol, name.ToUTF8());
+              if (strcasecmp(xcol, col_name) == 0)
+                ok_name_column = true;
+            }
+          if (one_way == true)
+            {
+              strcpy(xcol, one_way_from_to.ToUTF8());
+              if (strcasecmp(xcol, col_name) == 0)
+                ok_oneway_tofrom = true;
+            }
+          if (one_way == true)
+            {
+              strcpy(xcol, one_way_to_from.ToUTF8());
+              if (strcasecmp(xcol, col_name) == 0)
+                ok_oneway_fromto = true;
+            }
+        }
+      sqlite3_free_table(results);
+    }
+  if (ok_from_column == true && ok_to_column == true)
+    ;
+  else
+    goto abort;
+  if (name.Len() > 0 && ok_name_column == false)
+    goto abort;
+  if (ok_cost_column == false)
+    goto abort;
+  if (one_way == true && ok_oneway_tofrom == false)
+    goto abort;
+  if (one_way == true && ok_oneway_fromto == false)
+    goto abort;
+// checking column types
+  p_graph = new Network();
+  strcpy(xname, from.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql = wxT("SELECT ") + wxString::FromUTF8(xname);
+  strcpy(xname, to.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql += wxT(", ") + wxString::FromUTF8(xname);
+  strcpy(xname, cost.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql += wxT(", ") + wxString::FromUTF8(xname);
+  col_n = 3;
+  if (one_way == true)
+    {
+      strcpy(xname, one_way_to_from.ToUTF8());
+      DoubleQuotedSql(xname);
+      sql += wxT(", ") + wxString::FromUTF8(xname);
+      tofrom_n = col_n;
+      col_n++;
+      strcpy(xname, one_way_from_to.ToUTF8());
+      DoubleQuotedSql(xname);
+      sql += wxT(", ") + wxString::FromUTF8(xname);
+      fromto_n = col_n;
+      col_n++;
+    }
+  strcpy(xname, table.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql += wxT(" FROM ") + wxString::FromUTF8(xname);
+  strcpy(xsql, sql.ToUTF8());
+  ret = sqlite3_prepare_v2(SqliteHandle, xsql, strlen(xsql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    {
+      wxString err = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
+      wxMessageBox(wxT("SQL error: ") + err, wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      goto abort;
+    }
+  n_columns = sqlite3_column_count(stmt);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          // the NodeFrom type 
+          type = sqlite3_column_type(stmt, 0);
+          if (type == SQLITE_NULL)
+            from_null = true;
+          if (type == SQLITE_INTEGER)
+            {
+              from_int = true;
+              id_from = sqlite3_column_int64(stmt, 0);
+              p_graph->InsertNode(id_from);
+            }
+          if (type == SQLITE_FLOAT)
+            from_double = true;
+          if (type == SQLITE_TEXT)
+            {
+              from_text = true;
+              strcpy(code_from, (char *) sqlite3_column_text(stmt, 0));
+              p_graph->InsertNode(code_from);
+            }
+          if (type == SQLITE_BLOB)
+            from_blob = true;
+          // the NodeTo type 
+          type = sqlite3_column_type(stmt, 1);
+          if (type == SQLITE_NULL)
+            to_null = true;
+          if (type == SQLITE_INTEGER)
+            {
+              to_int = true;
+              id_to = sqlite3_column_int64(stmt, 1);
+              p_graph->InsertNode(id_to);
+            }
+          if (type == SQLITE_FLOAT)
+            to_double = true;
+          if (type == SQLITE_TEXT)
+            {
+              to_text = true;
+              strcpy(code_to, (char *) sqlite3_column_text(stmt, 1));
+              p_graph->InsertNode(code_to);
+            }
+          if (type == SQLITE_BLOB)
+            to_blob = true;
+          // the Cost type 
+          type = sqlite3_column_type(stmt, 2);
+          if (type == SQLITE_NULL)
+            cost_null = true;
+          if (type == SQLITE_TEXT)
+            cost_text = true;
+          if (type == SQLITE_BLOB)
+            cost_blob = true;
+          col_n = 3;
+          if (one_way == true)
+            {
+              // the FromTo type
+              type = sqlite3_column_type(stmt, col_n);
+              col_n++;
+              if (type == SQLITE_NULL)
+                fromto_null = true;
+              if (type == SQLITE_FLOAT)
+                fromto_double = true;
+              if (type == SQLITE_TEXT)
+                fromto_text = true;
+              if (type == SQLITE_BLOB)
+                fromto_blob = true;
+              // the ToFrom type 
+              type = sqlite3_column_type(stmt, col_n);
+              col_n++;
+              if (type == SQLITE_NULL)
+                tofrom_null = true;
+              if (type == SQLITE_FLOAT)
+                tofrom_double = true;
+              if (type == SQLITE_TEXT)
+                tofrom_text = true;
+              if (type == SQLITE_BLOB)
+                tofrom_blob = true;
+            }
+      } else
+        {
+          wxString err = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
+          wxMessageBox(wxT("sqlite3_step error: ") + err, wxT("spatialite_gui"),
+                       wxOK | wxICON_ERROR, this);
+          sqlite3_finalize(stmt);
+          goto abort;
+        }
+    }
+  sqlite3_finalize(stmt);
+  ret = 1;
+  if (from_null == true)
+    ret = 0;
+  if (from_blob == true)
+    ret = 0;
+  if (from_double == true)
+    ret = 0;
+  if (to_null == true)
+    ret = 0;
+  if (to_blob == true)
+    ret = 0;
+  if (to_double == true)
+    ret = 0;
+  if (cost_null == true)
+    ret = 0;
+  if (cost_blob == true)
+    ret = 0;
+  if (cost_text == true)
+    ret = 0;
+  if (one_way == true)
+    {
+      if (fromto_null == true)
+        ret = 0;
+      if (fromto_blob == true)
+        ret = 0;
+      if (fromto_text == true)
+        ret = 0;
+      if (fromto_double == true)
+        ret = 0;
+      if (tofrom_null == true)
+        ret = 0;
+      if (tofrom_blob == true)
+        ret = 0;
+      if (tofrom_text == true)
+        ret = 0;
+      if (tofrom_double == true)
+        ret = 0;
+    }
+  if (!ret)
+    goto abort;
+  if (from_int == true && to_int == true)
+    {
+      // each node is identified by an INTEGER id 
+      p_graph->SetNodeCode(false);
+  } else if (from_text == true && to_text == true)
+    {
+      // each node is identified by a TEXT code
+      p_graph->SetNodeCode(true);
+  } else
+    goto abort;
+  p_graph->InitNodes();
+// checking topological consistency 
+  strcpy(xname, from.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql = wxT("SELECT ROWID, ") + wxString::FromUTF8(xname);
+  strcpy(xname, to.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql += wxT(", ") + wxString::FromUTF8(xname);
+  strcpy(xname, cost.ToUTF8());
+  DoubleQuotedSql(xname);
+  strcpy(xname, cost.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql += wxT(", ") + wxString::FromUTF8(xname);
+  col_n = 4;
+  if (one_way == true)
+    {
+      strcpy(xname, one_way_to_from.ToUTF8());
+      DoubleQuotedSql(xname);
+      sql += wxT(", ") + wxString::FromUTF8(xname);
+      tofrom_n = col_n;
+      col_n++;
+      strcpy(xname, one_way_from_to.ToUTF8());
+      DoubleQuotedSql(xname);
+      sql += wxT(", ") + wxString::FromUTF8(xname);
+      fromto_n = col_n;
+      col_n++;
+    }
+  strcpy(xname, table.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql += wxT(" FROM ") + wxString::FromUTF8(xname);
+  strcpy(xsql, sql.ToUTF8());
+  ret = sqlite3_prepare_v2(SqliteHandle, xsql, strlen(xsql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    {
+      wxString err = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
+      wxMessageBox(wxT("SQL error: ") + err, wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      goto abort;
+    }
+  n_columns = sqlite3_column_count(stmt);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          fromto = true;
+          tofrom = true;
+          if (p_graph->IsNodeCode() == true)
+            {
+              id_from = -1;
+              id_to = -1;
+          } else
+            {
+              *code_from = '\0';
+              *code_to = '\0';
+            }
+          // fetching the ROWID 
+          rowid = sqlite3_column_int64(stmt, 0);
+          // fetching the NodeFrom value
+          if (p_graph->IsNodeCode() == true)
+            strcpy(code_from, (char *) sqlite3_column_text(stmt, 1));
+          else
+            id_from = sqlite3_column_int64(stmt, 1);
+          // fetching the NodeTo value
+          if (p_graph->IsNodeCode() == true)
+            strcpy(code_to, (char *) sqlite3_column_text(stmt, 2));
+          else
+            id_to = sqlite3_column_int64(stmt, 2);
+          // fetching the Cost value 
+          cost_val = sqlite3_column_double(stmt, 3);
+          if (one_way == true)
+            {
+              // fetching the OneWay-FromTo value
+              fromto = sqlite3_column_int(stmt, fromto_n);
+              // fetching the OneWay-ToFrom value
+              tofrom = sqlite3_column_int(stmt, tofrom_n);
+            }
+          if (cost_val <= 0.0)
+            p_graph->SetError();
+          if (bidirectional == true)
+            {
+              if (fromto)
+                {
+                  if (p_graph->IsNodeCode() == true)
+                    p_graph->AddArc(rowid, code_from, code_to, cost_val);
+                  else
+                    p_graph->AddArc(rowid, id_from, id_to, cost_val);
+                }
+              if (tofrom)
+                {
+                  if (p_graph->IsNodeCode() == true)
+                    p_graph->AddArc(rowid, code_to, code_from, cost_val);
+                  else
+                    p_graph->AddArc(rowid, id_to, id_from, cost_val);
+                }
+          } else
+            {
+              if (p_graph->IsNodeCode() == true)
+                p_graph->AddArc(rowid, code_from, code_to, cost_val);
+              else
+                p_graph->AddArc(rowid, id_from, id_to, cost_val);
+            }
+          if (p_graph->IsError() == true)
+            {
+              sqlite3_finalize(stmt);
+              goto abort;
+            }
+      } else
+        {
+          wxString err = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
+          wxMessageBox(wxT("sqlite3_step error: ") + err, wxT("spatialite_gui"),
+                       wxOK | wxICON_ERROR, this);
+          sqlite3_finalize(stmt);
+          goto abort;
+        }
+    }
+  sqlite3_finalize(stmt);
+  ::wxEndBusyCursor();
+  wr =
+    CreateNetwork(p_graph, table, from, to, name, dataTableName,
+                  virtualTableName);
+  if (wr == true)
+    {
+      endMsg =
+        wxT("OK: VirtualNetwork table '") + table +
+        wxT("_net' successfully created");
+      wxMessageBox(endMsg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
+                   this);
+  } else
+    {
+      endMsg =
+        wxT("DB ERROR: VirtualNetwork table '") + table +
+        wxT("_net' was not created");
+      wxMessageBox(endMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+    }
+  if (p_graph)
+    delete p_graph;
+  InitTableTree();
+  return;
+abort:
+  ::wxEndBusyCursor();
+  msg =
+    wxT
+    ("It's impossible to build a Network using the given configuration;\nsome fatal error occurred\n\n");
+  msg += wxT("please note: using the 'spatialite_network' command-line tool\n");
+  msg +=
+    wxT
+    ("you can obtain a full detailed report explaining causes for this failure");
+  wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+  if (p_graph)
+    delete p_graph;
+}
+
+void
+  MyFrame::OutputNetNode(unsigned char *auxbuf, int *size, int ind,
+                         bool node_code, int max_node_length, NetNode * pN,
+                         int endian_arch, bool aStarSupported)
+{
+//
+// exporting a Node into NETWORK-DATA
+//
+  int n_star;
+  int i;
+  NetArc **arc_array;
+  NetArc *pA;
+  unsigned char *out = auxbuf;
+  *out++ = GAIA_NET_NODE;
+  gaiaExport32(out, ind, 1, endian_arch); // the Node internal index 
+  out += 4;
+  if (node_code)
+    {
+      // Nodes are identified by a TEXT Code 
+      memset(out, '\0', max_node_length);
+      strcpy((char *) out, pN->GetCode().ToUTF8());
+      out += max_node_length;
+  } else
+    {
+      // Nodes are identified by an INTEGER Id 
+      gaiaExportI64(out, pN->GetId(), 1, endian_arch);
+      out += 8;
+    }
+  if (aStarSupported)
+    {
+      // in order to support the A* algorithm [X,Y] are required for each node
+      gaiaExport64(out, pN->GetX(), 1, endian_arch);
+      out += 8;
+      gaiaExport64(out, pN->GetY(), 1, endian_arch);
+      out += 8;
+    }
+  arc_array = pN->PrepareOutcomings(&n_star);
+  gaiaExport16(out, n_star, 1, endian_arch);  // # of outcoming arcs
+  out += 2;
+  for (i = 0; i < n_star; i++)
+    {
+      // exporting the outcoming arcs 
+      pA = *(arc_array + i);
+      *out++ = GAIA_NET_ARC;
+      gaiaExportI64(out, pA->GetRowId(), 1, endian_arch); // the Arc rowid
+      out += 8;
+      gaiaExport32(out, pA->GetTo()->GetInternalIndex(), 1, endian_arch); // the ToNode internal index
+      out += 4;
+      gaiaExport64(out, pA->GetCost(), 1, endian_arch); // the Arc Cost 
+      out += 8;
+      *out++ = GAIA_NET_END;
+    }
+  if (arc_array)
+    delete[]arc_array;
+  *out++ = GAIA_NET_END;
+  *size = out - auxbuf;
+}
+
+bool MyFrame::CreateNetwork(Network * p_graph, wxString & table,
+                            wxString & from, wxString & to,
+                            wxString & geometry, wxString & name,
+                            bool aStarSupported, double aStarCoeff,
+                            wxString & dataTableName,
+                            wxString & virtualTableName)
+{
+//
+// creates the NETWORK-DATA table 
+//
+  int ret;
+  wxString sql;
+  char xsql[1024];
+  char *errMsg = NULL;
+  unsigned char *auxbuf = new unsigned char[MAX_BLOCK];
+  unsigned char *buf = new unsigned char[MAX_BLOCK];
+  unsigned char *out;
+  sqlite3_stmt *stmt;
+  int i;
+  int size;
+  int endian_arch = gaiaEndianArch();
+  NetNode *pN;
+  int pk = 0;
+  int nodes_cnt = 0;
+  int len;
+  bool net_data_exists = false;
+  bool net_exists = false;
+  bool delete_existing = false;
+  char xname[1024];
+  net_data_exists = TableAlreadyExists(dataTableName);
+  net_exists = TableAlreadyExists(virtualTableName);
+  if (net_data_exists == true || net_exists == true)
+    {
+      // asking permission to overwrite existing tables
+      wxString msg;
+      if (net_data_exists == true)
+        msg +=
+          wxT("A table named '") + dataTableName + wxT("' already exists\n");
+      if (net_exists == true)
+        msg +=
+          wxT("A table named '") + virtualTableName + wxT("' already exists\n");
+      msg += wxT("\nDo you allow DROPping existing table(s) ?");
+      wxMessageDialog confirm(this, msg, wxT("Confirm overwrite"),
+                              wxYES_NO | wxICON_QUESTION);
+      ret = confirm.ShowModal();
+      if (ret == wxID_YES)
+        delete_existing = true;
+    }
+  ::wxBeginBusyCursor();
+  for (i = 0; i < p_graph->GetNumNodes(); i++)
+    {
+      // setting the internal index to each Node 
+      pN = p_graph->GetSortedNode(i);
+      pN->SetInternalIndex(i);
+    }
+// starts a transaction 
+  ret = sqlite3_exec(SqliteHandle, "BEGIN", NULL, NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("BEGIN error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      goto abort;
+    }
+  if (delete_existing == true)
+    {
+      strcpy(xname, virtualTableName.ToUTF8());
+      DoubleQuotedSql(xname);
+      sql = wxT("DROP TABLE IF EXISTS ") + wxString::FromUTF8(xname);
+      strcpy(xsql, sql.ToUTF8());
+      ret = sqlite3_exec(SqliteHandle, xsql, NULL, NULL, &errMsg);
+      if (ret != SQLITE_OK)
+        {
+          wxMessageBox(wxT("DROP TABLE error: ") + wxString::FromUTF8(errMsg),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+          sqlite3_free(errMsg);
+          goto abort;
+        }
+      strcpy(xname, dataTableName.ToUTF8());
+      DoubleQuotedSql(xname);
+      sql = wxT("DROP TABLE IF EXISTS ") + wxString::FromUTF8(xname);
+      strcpy(xsql, sql.ToUTF8());
+      ret = sqlite3_exec(SqliteHandle, xsql, NULL, NULL, &errMsg);
+      if (ret != SQLITE_OK)
+        {
+          wxMessageBox(wxT("DROP TABLE error: ") + wxString::FromUTF8(errMsg),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+          sqlite3_free(errMsg);
+          goto abort;
+        }
+    }
+// creating the NETWORK-DATA table 
+  strcpy(xname, dataTableName.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql = wxT("CREATE TABLE ") + wxString::FromUTF8(xname);
+  sql += wxT(" (Id INTEGER PRIMARY KEY, NetworkData BLOB NOT NULL)");
+  strcpy(xsql, sql.ToUTF8());
+  ret = sqlite3_exec(SqliteHandle, xsql, NULL, NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("CREATE TABLE error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      goto abort;
+    }
+// preparing the SQL statement
+  strcpy(xname, dataTableName.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql =
+    wxT("INSERT INTO ") + wxString::FromUTF8(xname) +
+    wxT(" (Id, NetworkData) VALUES (?, ?)");
+  strcpy(xsql, sql.ToUTF8());
+  ret = sqlite3_prepare_v2(SqliteHandle, xsql, strlen(xsql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    {
+      wxString err = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
+      wxMessageBox(wxT("INSERT error: ") + err, wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      goto abort;
+    }
+  if (pk == 0)
+    {
+      // preparing the HEADER block 
+      out = buf;
+      if (aStarSupported)
+        *out++ = GAIA_NET64_A_STAR_START;
+      else
+        *out++ = GAIA_NET64_START;
+      *out++ = GAIA_NET_HEADER;
+      gaiaExport32(out, p_graph->GetNumNodes(), 1, endian_arch);  // how many Nodes are there
+      out += 4;
+      if (p_graph->IsNodeCode() == true)
+        *out++ = GAIA_NET_CODE; // Nodes are identified by a TEXT code 
+      else
+        *out++ = GAIA_NET_ID;   // Nodes are identified by an INTEGER id 
+      if (p_graph->IsNodeCode() == true)
+        *out++ = p_graph->GetMaxCodeLength(); // max TEXT code length
+      else
+        *out++ = 0x00;
+      // inserting the main Table name 
+      *out++ = GAIA_NET_TABLE;
+      len = table.Len() + 1;
+      gaiaExport16(out, len, 1, endian_arch); // the Table Name length, including last '\0'
+      out += 2;
+      memset(out, '\0', len);
+      strcpy((char *) out, table.ToUTF8());
+      out += len;
+      // inserting the NodeFrom column name 
+      *out++ = GAIA_NET_FROM;
+      len = from.Len() + 1;
+      gaiaExport16(out, len, 1, endian_arch); // the NodeFrom column Name length, including last '\0'
+      out += 2;
+      memset(out, '\0', len);
+      strcpy((char *) out, from.ToUTF8());
+      out += len;
+      // inserting the NodeTo column name
+      *out++ = GAIA_NET_TO;
+      len = to.Len() + 1;
+      gaiaExport16(out, len, 1, endian_arch); // the NodeTo column Name length, including last '\0'
+      out += 2;
+      memset(out, '\0', len);
+      strcpy((char *) out, to.ToUTF8());
+      out += len;
+      // inserting the Geometry column name
+      *out++ = GAIA_NET_GEOM;
+      len = geometry.Len() + 1;
+      gaiaExport16(out, len, 1, endian_arch); // the Geometry column Name length, including last '\0'
+      out += 2;
+      memset(out, '\0', len);
+      strcpy((char *) out, geometry.ToUTF8());
+      out += len;
+      // inserting the Name column name - may be empty
+      *out++ = GAIA_NET_NAME;
+      if (name.Len() == 0)
+        len = 1;
+      else
+        len = name.Len() + 1;
+      gaiaExport16(out, len, 1, endian_arch); // the Name column Name length, including last '\0'
+      out += 2;
+      memset(out, '\0', len);
+      if (name.Len() > 0)
+        strcpy((char *) out, name.ToUTF8());
+      out += len;
+      if (aStarSupported)
+        {
+          // inserting the A* Heuristic Coeff
+          *out++ = GAIA_NET_A_STAR_COEFF;
+          gaiaExport64(out, aStarCoeff, 1, endian_arch);
+          out += 8;
+        }
+      *out++ = GAIA_NET_END;
+      // INSERTing the Header block 
+      sqlite3_reset(stmt);
+      sqlite3_clear_bindings(stmt);
+      sqlite3_bind_int64(stmt, 1, pk);
+      sqlite3_bind_blob(stmt, 2, buf, out - buf, SQLITE_STATIC);
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+        ;
+      else
+        {
+          wxString err = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
+          wxMessageBox(wxT("sqlite3_step error: ") + err, wxT("spatialite_gui"),
+                       wxOK | wxICON_ERROR, this);
+          sqlite3_finalize(stmt);
+          goto abort;
+        }
+      pk++;
+      // preparing a new block 
+      out = buf;
+      *out++ = GAIA_NET_BLOCK;
+      gaiaExport16(out, 0, 1, endian_arch); // how many Nodes are into this block 
+      out += 2;
+      nodes_cnt = 0;
+    }
+  for (i = 0; i < p_graph->GetNumNodes(); i++)
+    {
+      // looping on each Node 
+      pN = p_graph->GetSortedNode(i);
+      OutputNetNode(auxbuf, &size, i, p_graph->IsNodeCode(),
+                    p_graph->GetMaxCodeLength(), pN, endian_arch,
+                    aStarSupported);
+      if (size >= (MAX_BLOCK - (out - buf)))
+        {
+          // inserting the last block 
+          gaiaExport16(buf + 1, nodes_cnt, 1, endian_arch); // how many Nodes are into this block
+          sqlite3_reset(stmt);
+          sqlite3_clear_bindings(stmt);
+          sqlite3_bind_int64(stmt, 1, pk);
+          sqlite3_bind_blob(stmt, 2, buf, out - buf, SQLITE_STATIC);
+          ret = sqlite3_step(stmt);
+          if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+            ;
+          else
+            {
+              wxString err = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
+              wxMessageBox(wxT("sqlite3_step error: ") + err,
+                           wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+              sqlite3_finalize(stmt);
+              goto abort;
+            }
+          pk++;
+          // preparing a new block 
+          out = buf;
+          *out++ = GAIA_NET_BLOCK;
+          gaiaExport16(out, 0, 1, endian_arch); // how many Nodes are into this block
+          out += 2;
+          nodes_cnt = 0;
+        }
+      // inserting the current Node into the block 
+      nodes_cnt++;
+      memcpy(out, auxbuf, size);
+      out += size;
+    }
+  if (nodes_cnt)
+    {
+      // inserting the last block
+      gaiaExport16(buf + 1, nodes_cnt, 1, endian_arch); // how many Nodes are into this block
+      sqlite3_reset(stmt);
+      sqlite3_clear_bindings(stmt);
+      sqlite3_bind_int64(stmt, 1, pk);
+      sqlite3_bind_blob(stmt, 2, buf, out - buf, SQLITE_STATIC);
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+        ;
+      else
         {
           wxString err = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
           wxMessageBox(wxT("sqlite3_step error: ") + err, wxT("spatialite_gui"),
@@ -603,107 +1470,56 @@ void
         }
     }
   sqlite3_finalize(stmt);
-  ::wxEndBusyCursor();
-  wr =
-    CreateNetwork(p_graph, table, from, to, geometry, name, aStarSupported,
-                  min_a_star_coeff);
-  if (wr == true)
+// creating the VirtualNetwork NET-table
+  strcpy(xname, virtualTableName.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql = wxT("CREATE VIRTUAL TABLE ") + wxString::FromUTF8(xname);
+  sql += wxT(" USING VirtualNetwork(");
+  strcpy(xname, dataTableName.ToUTF8());
+  DoubleQuotedSql(xname);
+  sql += wxString::FromUTF8(xname) + wxT(")");
+  strcpy(xsql, sql.ToUTF8());
+  ret = sqlite3_exec(SqliteHandle, xsql, NULL, NULL, &errMsg);
+  if (ret != SQLITE_OK)
     {
-      endMsg =
-        wxT("OK: VirtualNetwork table '") + table +
-        wxT("_net' successfully created");
-      wxMessageBox(endMsg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
-                   this);
-  } else
+      wxMessageBox(wxT("CREATE VIRTUAL TABLE error: ") +
+                   wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      goto abort;
+    }
+// commits the transaction 
+  ret = sqlite3_exec(SqliteHandle, "COMMIT", NULL, NULL, &errMsg);
+  if (ret != SQLITE_OK)
     {
-      endMsg =
-        wxT("DB ERROR: VirtualNetwork table '") + table +
-        wxT("_net' was not created");
-      wxMessageBox(endMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      wxMessageBox(wxT("COMMIT error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      goto abort;
     }
-  if (p_graph)
-    delete p_graph;
-  InitTableTree();
-  return;
+  if (buf)
+    delete[]buf;
+  if (auxbuf)
+    delete[]auxbuf;
+  ::wxEndBusyCursor();
+  return true;
 abort:
   ::wxEndBusyCursor();
-  msg =
-    wxT
-    ("It's impossible to build a Network using the given configuration;\nsome fatal error occurred\n\n");
-  msg += wxT("please note: using the 'spatialite_network' command-line tool\n");
-  msg +=
-    wxT
-    ("you can obtain a full detailed report explaining causes for this failure");
-  wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
-  if (p_graph)
-    delete p_graph;
-}
-
-void
-  MyFrame::OutputNetNode(unsigned char *auxbuf, int *size, int ind,
-                         bool node_code, int max_node_length, NetNode * pN,
-                         int endian_arch, bool aStarSupported)
-{
-//
-// exporting a Node into NETWORK-DATA
-//
-  int n_star;
-  int i;
-  NetArc **arc_array;
-  NetArc *pA;
-  unsigned char *out = auxbuf;
-  *out++ = GAIA_NET_NODE;
-  gaiaExport32(out, ind, 1, endian_arch); // the Node internal index 
-  out += 4;
-  if (node_code)
-    {
-      // Nodes are identified by a TEXT Code 
-      memset(out, '\0', max_node_length);
-      strcpy((char *) out, pN->GetCode().ToUTF8());
-      out += max_node_length;
-  } else
-    {
-      // Nodes are identified by an INTEGER Id 
-      gaiaExportI64(out, pN->GetId(), 1, endian_arch);
-      out += 8;
-    }
-  if (aStarSupported)
-    {
-      // in order to support the A* algorithm [X,Y] are required for each node
-      gaiaExport64(out, pN->GetX(), 1, endian_arch);
-      out += 8;
-      gaiaExport64(out, pN->GetY(), 1, endian_arch);
-      out += 8;
-    }
-  arc_array = pN->PrepareOutcomings(&n_star);
-  gaiaExport16(out, n_star, 1, endian_arch);  // # of outcoming arcs
-  out += 2;
-  for (i = 0; i < n_star; i++)
-    {
-      // exporting the outcoming arcs 
-      pA = *(arc_array + i);
-      *out++ = GAIA_NET_ARC;
-      gaiaExportI64(out, pA->GetRowId(), 1, endian_arch); // the Arc rowid
-      out += 8;
-      gaiaExport32(out, pA->GetTo()->GetInternalIndex(), 1, endian_arch); // the ToNode internal index
-      out += 4;
-      gaiaExport64(out, pA->GetCost(), 1, endian_arch); // the Arc Cost 
-      out += 8;
-      *out++ = GAIA_NET_END;
-    }
-  if (arc_array)
-    delete[]arc_array;
-  *out++ = GAIA_NET_END;
-  *size = out - auxbuf;
+  if (buf)
+    delete[]buf;
+  if (auxbuf)
+    delete[]auxbuf;
+  return true;
+  return false;
 }
 
 bool MyFrame::CreateNetwork(Network * p_graph, wxString & table,
-                            wxString & from, wxString & to, wxString & geometry,
-                            wxString & name, bool aStarSupported,
-                            double aStarCoeff)
+                            wxString & from, wxString & to, wxString & name,
+                            wxString & dataTableName,
+                            wxString & virtualTableName)
 {
 //
-// creates the NETWORK-DATA table 
+// creates the NETWORK-DATA table . NO-GEOMETRY
 //
   int ret;
   wxString sql;
@@ -724,18 +1540,18 @@ bool MyFrame::CreateNetwork(Network * p_graph, wxString & table,
   bool net_exists = false;
   bool delete_existing = false;
   char xname[1024];
-  wxString data_table = table + wxT("_net_data");
-  wxString net_table = table + wxT("_net");
-  net_data_exists = TableAlreadyExists(data_table);
-  net_exists = TableAlreadyExists(net_table);
+  net_data_exists = TableAlreadyExists(dataTableName);
+  net_exists = TableAlreadyExists(virtualTableName);
   if (net_data_exists == true || net_exists == true)
     {
       // asking permission to overwrite existing tables
       wxString msg;
       if (net_data_exists == true)
-        msg += wxT("A table named '") + data_table + wxT("' already exists\n");
+        msg +=
+          wxT("A table named '") + dataTableName + wxT("' already exists\n");
       if (net_exists == true)
-        msg += wxT("A table named '") + net_table + wxT("' already exists\n");
+        msg +=
+          wxT("A table named '") + virtualTableName + wxT("' already exists\n");
       msg += wxT("\nDo you allow DROPping existing table(s) ?");
       wxMessageDialog confirm(this, msg, wxT("Confirm overwrite"),
                               wxYES_NO | wxICON_QUESTION);
@@ -761,7 +1577,7 @@ bool MyFrame::CreateNetwork(Network * p_graph, wxString & table,
     }
   if (delete_existing == true)
     {
-      strcpy(xname, net_table.ToUTF8());
+      strcpy(xname, virtualTableName.ToUTF8());
       DoubleQuotedSql(xname);
       sql = wxT("DROP TABLE IF EXISTS ") + wxString::FromUTF8(xname);
       strcpy(xsql, sql.ToUTF8());
@@ -773,7 +1589,7 @@ bool MyFrame::CreateNetwork(Network * p_graph, wxString & table,
           sqlite3_free(errMsg);
           goto abort;
         }
-      strcpy(xname, data_table.ToUTF8());
+      strcpy(xname, dataTableName.ToUTF8());
       DoubleQuotedSql(xname);
       sql = wxT("DROP TABLE IF EXISTS ") + wxString::FromUTF8(xname);
       strcpy(xsql, sql.ToUTF8());
@@ -787,7 +1603,7 @@ bool MyFrame::CreateNetwork(Network * p_graph, wxString & table,
         }
     }
 // creating the NETWORK-DATA table 
-  strcpy(xname, data_table.ToUTF8());
+  strcpy(xname, dataTableName.ToUTF8());
   DoubleQuotedSql(xname);
   sql = wxT("CREATE TABLE ") + wxString::FromUTF8(xname);
   sql += wxT(" (Id INTEGER PRIMARY KEY, NetworkData BLOB NOT NULL)");
@@ -801,7 +1617,7 @@ bool MyFrame::CreateNetwork(Network * p_graph, wxString & table,
       goto abort;
     }
 // preparing the SQL statement
-  strcpy(xname, data_table.ToUTF8());
+  strcpy(xname, dataTableName.ToUTF8());
   DoubleQuotedSql(xname);
   sql =
     wxT("INSERT INTO ") + wxString::FromUTF8(xname) +
@@ -819,10 +1635,7 @@ bool MyFrame::CreateNetwork(Network * p_graph, wxString & table,
     {
       // preparing the HEADER block 
       out = buf;
-      if (aStarSupported)
-        *out++ = GAIA_NET64_A_STAR_START;
-      else
-        *out++ = GAIA_NET64_START;
+      *out++ = GAIA_NET64_START;
       *out++ = GAIA_NET_HEADER;
       gaiaExport32(out, p_graph->GetNumNodes(), 1, endian_arch);  // how many Nodes are there
       out += 4;
@@ -860,11 +1673,10 @@ bool MyFrame::CreateNetwork(Network * p_graph, wxString & table,
       out += len;
       // inserting the Geometry column name
       *out++ = GAIA_NET_GEOM;
-      len = geometry.Len() + 1;
+      len = 1;
       gaiaExport16(out, len, 1, endian_arch); // the Geometry column Name length, including last '\0'
       out += 2;
       memset(out, '\0', len);
-      strcpy((char *) out, geometry.ToUTF8());
       out += len;
       // inserting the Name column name - may be empty
       *out++ = GAIA_NET_NAME;
@@ -878,13 +1690,6 @@ bool MyFrame::CreateNetwork(Network * p_graph, wxString & table,
       if (name.Len() > 0)
         strcpy((char *) out, name.ToUTF8());
       out += len;
-      if (aStarSupported)
-        {
-          // inserting the A* Heuristic Coeff
-          *out++ = GAIA_NET_A_STAR_COEFF;
-          gaiaExport64(out, aStarCoeff, 1, endian_arch);
-          out += 8;
-        }
       *out++ = GAIA_NET_END;
       // INSERTing the Header block 
       sqlite3_reset(stmt);
@@ -915,8 +1720,7 @@ bool MyFrame::CreateNetwork(Network * p_graph, wxString & table,
       // looping on each Node 
       pN = p_graph->GetSortedNode(i);
       OutputNetNode(auxbuf, &size, i, p_graph->IsNodeCode(),
-                    p_graph->GetMaxCodeLength(), pN, endian_arch,
-                    aStarSupported);
+                    p_graph->GetMaxCodeLength(), pN, endian_arch, 0);
       if (size >= (MAX_BLOCK - (out - buf)))
         {
           // inserting the last block 
@@ -971,11 +1775,11 @@ bool MyFrame::CreateNetwork(Network * p_graph, wxString & table,
     }
   sqlite3_finalize(stmt);
 // creating the VirtualNetwork NET-table
-  strcpy(xname, net_table.ToUTF8());
+  strcpy(xname, virtualTableName.ToUTF8());
   DoubleQuotedSql(xname);
   sql = wxT("CREATE VIRTUAL TABLE ") + wxString::FromUTF8(xname);
   sql += wxT(" USING VirtualNetwork(");
-  strcpy(xname, data_table.ToUTF8());
+  strcpy(xname, dataTableName.ToUTF8());
   DoubleQuotedSql(xname);
   sql += wxString::FromUTF8(xname) + wxT(")");
   strcpy(xsql, sql.ToUTF8());
@@ -1414,6 +2218,26 @@ NetNode *Network::ProcessNode(wxString & code, double x, double y,
   return NULL;
 }
 
+NetNode *Network::ProcessNode(sqlite3_int64 id, NetNode ** pOther)
+{
+//
+// inserts a new node or retrieves an already defined one 
+//
+  NetNode *pN = Find(id);
+  *pOther = NULL;
+  return pN;
+}
+
+NetNode *Network::ProcessNode(wxString & code, NetNode ** pOther)
+{
+//
+// inserts a new node or retrieves an already defined one 
+//
+  NetNode *pN = Find(code);
+  *pOther = NULL;
+  return pN;
+}
+
 void
   Network::AddArc(sqlite3_int64 rowid, sqlite3_int64 id_from,
                   sqlite3_int64 id_to, double node_from_x, double node_from_y,
@@ -1488,6 +2312,78 @@ void
   pFrom->AddOutcoming(pA);
 }
 
+void
+  Network::AddArc(sqlite3_int64 rowid, sqlite3_int64 id_from,
+                  sqlite3_int64 id_to, double cost)
+{
+//
+// inserting an arc into the memory structures 
+//
+  NetNode *pFrom;
+  NetNode *pTo;
+  NetNode *pN2;
+  NetArc *pA;
+  pFrom = ProcessNode(id_from, &pN2);
+  if (pN2)
+    Error = true;
+  pTo = ProcessNode(id_to, &pN2);
+  if (pN2)
+    Error = true;
+  if (!pFrom)
+    Error = true;
+  if (!pTo)
+    Error = true;
+  if (pFrom == pTo)
+    Error = true;
+  if (Error == true)
+    return;
+  pA = new NetArc(rowid, pFrom, pTo, cost);
+  if (!FirstArc)
+    FirstArc = pA;
+  if (LastArc)
+    LastArc->SetNext(pA);
+  LastArc = pA;
+// updating Node connections 
+  pFrom->AddOutcoming(pA);
+}
+
+void
+  Network::AddArc(sqlite3_int64 rowid, const char *code_from,
+                  const char *code_to, double cost)
+{
+//
+// inserting an arc into the memory structures 
+//
+  NetNode *pFrom;
+  NetNode *pTo;
+  NetNode *pN2;
+  NetArc *pA;
+  wxString stCode = wxString::FromUTF8(code_from);
+  pFrom = ProcessNode(stCode, &pN2);
+  if (pN2)
+    Error = true;
+  stCode = wxString::FromUTF8(code_to);
+  pTo = ProcessNode(stCode, &pN2);
+  if (pN2)
+    Error = true;
+  if (!pFrom)
+    Error = true;
+  if (!pTo)
+    Error = true;
+  if (pFrom == pTo)
+    Error = true;
+  if (Error == true)
+    return;
+  pA = new NetArc(rowid, pFrom, pTo, cost);
+  if (!FirstArc)
+    FirstArc = pA;
+  if (LastArc)
+    LastArc->SetNext(pA);
+  LastArc = pA;
+// updating Node connections 
+  pFrom->AddOutcoming(pA);
+}
+
 void Network::Sort()
 {
 //
diff --git a/Objects.cpp b/Objects.cpp
index a25d3fd..10f45ac 100644
--- a/Objects.cpp
+++ b/Objects.cpp
@@ -35,9 +35,10 @@ MyObject::MyObject(int type, wxString & name)
   Column = wxT("");
   DbAlias = wxT("");
   Temporary = false;
+  Coverage = false;
 }
 
-MyObject::MyObject(int type, wxString & name, bool tmp)
+MyObject::MyObject(int type, wxString & name, bool tmp, bool coverage)
 {
 //
 // constructor - TreeItemData
@@ -47,6 +48,7 @@ MyObject::MyObject(int type, wxString & name, bool tmp)
   Column = wxT("");
   DbAlias = wxT("");
   Temporary = tmp;
+  Coverage = coverage;
 }
 
 MyObject::MyObject(int type, wxString & name, wxString & column)
@@ -59,10 +61,11 @@ MyObject::MyObject(int type, wxString & name, wxString & column)
   Column = column;
   DbAlias = wxT("");
   Temporary = false;
+  Coverage = false;
 }
 
 MyObject::MyObject(int type, bool WXUNUSED(attached), wxString & dbAlias,
-                   wxString & name)
+                   wxString & name, bool coverage)
 {
 //
 // constructor - TreeItemData
@@ -72,6 +75,7 @@ MyObject::MyObject(int type, bool WXUNUSED(attached), wxString & dbAlias,
   Column = wxT("");
   DbAlias = dbAlias;
   Temporary = false;
+  Coverage = coverage;
 }
 
 void MyVariant::Copy(MyVariant * other)
@@ -481,6 +485,7 @@ MyColumnInfo::MyColumnInfo(wxString & name, bool pkey)
   Name = name;
   PrimaryKey = pkey;
   Geometry = false;
+  GPKGGeometry = false;
   GeometryIndex = false;
   MbrCache = false;
   Next = NULL;
@@ -495,6 +500,62 @@ MyIndexInfo::MyIndexInfo(wxString & name)
   Next = NULL;
 }
 
+bool MyIndexInfo::ContainsOnlyPrimaryKeyColumns(sqlite3 * sqlite,
+                                                wxString & indexName,
+                                                MyColumnInfo * first_column)
+{
+//
+// check if an Index does only contain Primary Key columns
+//
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  char *name;
+  char xname[2048];
+  wxString Name;
+  wxString sql;
+  int pk_cnt = 0;
+  int col_cnt = 0;
+  sql = wxT("PRAGMA index_info(");
+  strcpy(xname, indexName.ToUTF8());
+  MyFrame::DoubleQuotedSql(xname);
+  sql += wxString::FromUTF8(xname);
+  sql += wxT(")");
+  int ret = sqlite3_get_table(sqlite, sql.ToUTF8(), &results,
+                              &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, NULL);
+      sqlite3_free(errMsg);
+      return false;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          name = results[(i * columns) + 2];
+          Name = wxString::FromUTF8(name);
+          col_cnt++;
+          MyColumnInfo *elc = first_column;
+          while (elc)
+            {
+              if (elc->GetName() == Name && elc->IsPrimaryKey())
+                pk_cnt++;
+              elc = elc->GetNext();
+            }
+        }
+    }
+  sqlite3_free_table(results);
+  if (pk_cnt == col_cnt)
+    return true;
+  return false;
+}
+
 MyTriggerInfo::MyTriggerInfo(wxString & name)
 {
 //
@@ -598,6 +659,103 @@ void MyTableInfo::AddTrigger(wxString & name)
   LastTrigger = el;
 }
 
+void MyTableInfo::CheckGPKG(MyFrame * MainFrame, sqlite3 * handle,
+                            wxString & table)
+{
+//
+// checking for a GPKG Geometry
+//
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  const char *name;
+  const char *type;
+  wxString Name;
+  char *sql;
+  char xname[1024];
+  int ret;
+  int is_gpkg = 0;
+  char *xtable;
+
+  strcpy(xname, table.ToUTF8());
+  sql = sqlite3_mprintf("SELECT Count(*) FROM sqlite_master "
+                        "WHERE type = 'table' AND tbl_name = %Q AND sql LIKE '%%VirtualGPKG%%'",
+                        xname);
+  ret = sqlite3_get_table(handle, sql, &results, &rows, &columns, &errMsg);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("CheckGPKG error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, MainFrame);
+      sqlite3_free(errMsg);
+      return;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          is_gpkg = atoi(results[(i * columns) + 0]);
+        }
+    }
+  sqlite3_free_table(results);
+  if (!is_gpkg)
+    return;
+
+  strcpy(xname, table.ToUTF8());
+  xtable = gaiaDoubleQuotedSql(xname);
+  sql = sqlite3_mprintf("PRAGMA table_info(\"%s\")", xtable);
+  free(xtable);
+  ret = sqlite3_get_table(handle, sql, &results, &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("CheckGPKG error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, MainFrame);
+      sqlite3_free(errMsg);
+      return;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          name = results[(i * columns) + 1];
+          type = results[(i * columns) + 2];
+          if (strcasecmp(type, "POINT") == 0)
+            Name = wxString::FromUTF8(name);
+          if (strcasecmp(type, "LINESTRING") == 0)
+            Name = wxString::FromUTF8(name);
+          if (strcasecmp(type, "POLYGON") == 0)
+            Name = wxString::FromUTF8(name);
+          if (strcasecmp(type, "MULTIPOINT") == 0)
+            Name = wxString::FromUTF8(name);
+          if (strcasecmp(type, "MULTILINESTRING") == 0)
+            Name = wxString::FromUTF8(name);
+          if (strcasecmp(type, "MULTIPOLYGON") == 0)
+            Name = wxString::FromUTF8(name);
+          if (strcasecmp(type, "GEOMETRYCOLLECTION") == 0)
+            Name = wxString::FromUTF8(name);
+        }
+    }
+  sqlite3_free_table(results);
+  if (Name.Len() == 0)
+    return;
+  MyColumnInfo *elc = FirstColumn;
+  while (elc)
+    {
+      if (Name.CmpNoCase(elc->GetName()) == 0)
+        {
+          elc->SetGPKGGeometry();
+          break;
+        }
+      elc = elc->GetNext();
+    }
+}
+
 MyViewInfo::~MyViewInfo()
 {
 //
@@ -821,6 +979,35 @@ void AutoFDOTables::Add(const char *name, const int len)
   Last = el;
 }
 
+AutoGPKGTables::~AutoGPKGTables()
+{
+//
+// destructor - auto GPKG wrapper linked list
+//
+  AutoGPKGTable *el;
+  AutoGPKGTable *elN;
+  el = First;
+  while (el)
+    {
+      elN = el->GetNext();
+      delete el;
+      el = elN;
+    }
+}
+
+void AutoGPKGTables::Add(const char *name, const int len)
+{
+//
+// adding a table name to the auto GPKG wrapper linked list
+//
+  AutoGPKGTable *el = new AutoGPKGTable(name, len);
+  if (!First)
+    First = el;
+  if (Last)
+    Last->SetNext(el);
+  Last = el;
+}
+
 GeomColumn::GeomColumn(wxString & name, wxString & type, wxString & dims,
                        int srid, int idx)
 {
@@ -1540,7 +1727,7 @@ void TopologyList::Add(class MyTableTree * tree, wxTreeItemId & root,
 
 wxTreeItemId *TopologyList::FindNode(wxString & table)
 {
-// serching corresponding Topology Node (if any)
+// searching corresponding Topology Node (if any)
   Topology *pT = First;
   while (pT)
     {
@@ -1552,6 +1739,133 @@ wxTreeItemId *TopologyList::FindNode(wxString & table)
   return NULL;
 }
 
+RasterCoverage::RasterCoverage(MyTableTree * tree, wxTreeItemId & root,
+                               wxString & coverage, int srid)
+{
+// constructor: Raster Coverage Tree Node
+  Name = coverage;
+  wxString xname;
+  char bufSrid[64];
+  xname = Name;
+  sprintf(bufSrid, " [SRID=%d]", srid);
+  xname += wxString::FromUTF8(bufSrid);
+  CoverageNode = tree->AppendItem(root, xname);
+  tree->SetItemImage(CoverageNode, 22);
+  Next = NULL;
+}
+
+VectorCoverage::VectorCoverage(MyTableTree * tree, wxTreeItemId & root,
+                               wxString & coverage, int srid)
+{
+// constructor: Vector Coverage Tree Node
+  Name = coverage;
+  wxString xname;
+  char bufSrid[64];
+  xname = Name;
+  sprintf(bufSrid, " [SRID=%d]", srid);
+  xname += wxString::FromUTF8(bufSrid);
+  CoverageNode = tree->AppendItem(root, xname);
+  tree->SetItemImage(CoverageNode, 24);
+  Next = NULL;
+}
+
+wxTreeItemId *RasterCoverage::Check(wxString & table, bool * tile_data)
+{
+// checking if some table belongs to this Raster Coverage
+  *tile_data = false;
+  wxString cfr = Name + wxT("_sections");
+  if (cfr.CmpNoCase(table) == 0)
+    return &CoverageNode;
+  cfr = Name + wxT("_tiles");
+  if (cfr.CmpNoCase(table) == 0)
+    return &CoverageNode;
+  cfr = Name + wxT("_tile_data");
+  if (cfr.CmpNoCase(table) == 0)
+    {
+      *tile_data = true;
+      return &CoverageNode;
+    }
+  cfr = Name + wxT("_levels");
+  if (cfr.CmpNoCase(table) == 0)
+    return &CoverageNode;
+  return NULL;
+}
+
+void RasterCoverageList::Flush()
+{
+// resetting RasterCovreageList to initial empty state
+  RasterCoverage *pC;
+  RasterCoverage *pCn;
+  pC = First;
+  while (pC)
+    {
+      pCn = pC->GetNext();
+      delete pC;
+      pC = pCn;
+    }
+  First = NULL;
+  Last = NULL;
+  Count = 0;
+}
+
+void RasterCoverageList::Add(class MyTableTree * tree, wxTreeItemId & root,
+                             wxString & coverage, int srid)
+{
+// inserting a Raster Coverage into the list
+  RasterCoverage *pC = new RasterCoverage(tree, root, coverage, srid);
+  Count++;
+  if (First == NULL)
+    First = pC;
+  if (Last != NULL)
+    Last->SetNext(pC);
+  Last = pC;
+}
+
+wxTreeItemId *RasterCoverageList::FindNode(wxString & table, bool * tile_data)
+{
+// searching corresponding Topology Node (if any)
+  RasterCoverage *pC = First;
+  while (pC)
+    {
+      wxTreeItemId *node = pC->Check(table, tile_data);
+      if (node != NULL)
+        return node;
+      pC = pC->GetNext();
+    }
+  *tile_data = false;
+  return NULL;
+}
+
+void VectorCoverageList::Flush()
+{
+// resetting VectorCovreageList to initial empty state
+  VectorCoverage *pC;
+  VectorCoverage *pCn;
+  pC = First;
+  while (pC)
+    {
+      pCn = pC->GetNext();
+      delete pC;
+      pC = pCn;
+    }
+  First = NULL;
+  Last = NULL;
+  Count = 0;
+}
+
+void VectorCoverageList::Add(class MyTableTree * tree, wxTreeItemId & root,
+                             wxString & coverage, int srid)
+{
+// inserting a Vector Coverage into the list
+  VectorCoverage *pC = new VectorCoverage(tree, root, coverage, srid);
+  Count++;
+  if (First == NULL)
+    First = pC;
+  if (Last != NULL)
+    Last->SetNext(pC);
+  Last = pC;
+}
+
 PostGISColumn::PostGISColumn()
 {
 // constructor
@@ -2837,3 +3151,137 @@ bool TopologySet::CheckPrefix()
     }
   return false;
 }
+
+VectorCoverageSet::VectorCoverageSet(const char *name, int srid)
+{
+// constructor
+  Name = wxString::FromUTF8(name);
+  Srid = srid;
+}
+
+RasterCoverageSet::RasterCoverageSet(const char *name, int srid)
+{
+// constructor
+  Name = wxString::FromUTF8(name);
+  Srid = srid;
+}
+
+RasterCoverageItem::RasterCoverageItem(wxString & name, bool tile_data)
+{
+// constructor
+  Name = name;
+  TileData = tile_data;
+  Next = NULL;
+}
+
+TableViewItem::TableViewItem(wxString & name, bool is_view, bool is_virtual)
+{
+// constructor
+  Name = name;
+  View = is_view;
+  Virtual = is_virtual;
+  Geometry = false;
+  Next = NULL;
+}
+
+TableViewList::TableViewList()
+{
+// constructor
+  First = NULL;
+  Last = NULL;
+  Count = 0;
+  Sorted = NULL;
+}
+
+TableViewList::~TableViewList()
+{
+// destructor
+  TableViewItem *ptv;
+  TableViewItem *ptvN;
+  ptv = First;
+  while (ptv != NULL)
+    {
+      ptvN = ptv->GetNext();
+      delete ptv;
+      ptv = ptvN;
+    }
+  if (Sorted != NULL)
+    delete[]Sorted;
+}
+
+void TableViewList::Add(wxString & name, bool isView, bool isVirtual)
+{
+// adding a new item to the list
+  TableViewItem *item = new TableViewItem(name, isView, isVirtual);
+  if (First == NULL)
+    First = item;
+  if (Last != NULL)
+    Last->SetNext(item);
+  Last = item;
+}
+
+static int cmp_tables1(const void *p1, const void *p2)
+{
+//
+// compares two Tables or Views  by Name [for QSORT] 
+//
+  TableViewItem *ptv1 = *(TableViewItem **) p1;
+  TableViewItem *ptv2 = *((TableViewItem **) p2);
+  return ptv1->GetName().CmpNoCase(ptv2->GetName());
+}
+
+static int cmp_tables2(const void *p1, const void *p2)
+{
+//
+// compares two Tables or Views by Name [for BSEARCH] 
+//
+  TableViewItem *ptv1 = (TableViewItem *) p1;
+  TableViewItem *ptv2 = *((TableViewItem **) p2);
+  return ptv1->GetName().CmpNoCase(ptv2->GetName());
+}
+
+void TableViewList::PrepareSorted()
+{
+// preparing the array of sorted pointers
+  int cnt = 0;
+  TableViewItem *item = First;
+  while (item != NULL)
+    {
+      // counting how many items
+      cnt++;
+      item = item->GetNext();
+    }
+  Count = cnt;
+  if (Sorted != NULL)
+    delete[]Sorted;
+  if (Count == 0)
+    {
+      Sorted = NULL;
+      return;
+    }
+  Sorted = new TableViewItem *[Count];
+  cnt = 0;
+  item = First;
+  while (item != NULL)
+    {
+      // populating the sorted array
+      *(Sorted + cnt++) = item;
+      item = item->GetNext();
+    }
+  qsort(Sorted, Count, sizeof(TableViewItem *), cmp_tables1);
+}
+
+void TableViewList::SetGeometry(wxString & name)
+{
+// marking a Geometry Table or View
+  TableViewItem **ret;
+  TableViewItem ptv(name, false, false);
+  if (!Sorted)
+    return;
+  ret =
+    (TableViewItem **) bsearch(&ptv, Sorted, Count, sizeof(TableViewItem *),
+                               cmp_tables2);
+  if (!ret)
+    return;
+  (*ret)->SetGeometry();
+}
diff --git a/QueryView.cpp b/QueryView.cpp
index fd21686..131591f 100644
--- a/QueryView.cpp
+++ b/QueryView.cpp
@@ -136,6 +136,14 @@ void MyQueryView::SetHistoryStates()
 
 void MyQueryView::SetSql(wxString & sql, bool execute)
 {
+  bool coverage = false;
+  wxString tile_data_table;
+  SetSql(sql, execute, coverage, tile_data_table, true);
+}
+
+void MyQueryView::SetSql(wxString & sql, bool execute, bool coverage,
+                         wxString & tile_data_table, bool reset)
+{
 //
 // sets an SQL statement [and maybe executes it]
 //
@@ -148,7 +156,9 @@ void MyQueryView::SetSql(wxString & sql, bool execute)
           // current metadata style >= v.4.0.0
           MainFrame->InsertIntoLog(sql);
         }
-      if (MainFrame->GetRsView()->ExecuteSqlPre(sql, 0, true) == false)
+      if (MainFrame->GetRsView()->ExecuteSqlPre(sql, 0, true, coverage,
+                                                tile_data_table,
+                                                reset) == false)
         {
           if (metaDataType == METADATA_CURRENT)
             {
@@ -208,6 +218,7 @@ void MyQueryView::OnSqlGo(wxCommandEvent & WXUNUSED(event))
 //
 // executing an SQL statement
 //
+  wxString tile_data_name;
   int metaDataType = MainFrame->GetMetaDataType();
   wxString sql = SqlCtrl->GetValue();
   if (metaDataType == METADATA_CURRENT)
@@ -215,7 +226,8 @@ void MyQueryView::OnSqlGo(wxCommandEvent & WXUNUSED(event))
       // current metadata style >= v.4.0.0
       MainFrame->InsertIntoLog(sql);
     }
-  if (MainFrame->GetRsView()->ExecuteSqlPre(sql, 0, true) == false)
+  if (MainFrame->GetRsView()->ExecuteSqlPre(sql, 0, true, false, tile_data_name,
+                                            true) == false)
     {
       if (metaDataType == METADATA_CURRENT)
         {
@@ -276,16 +288,21 @@ void MyQueryView::OnHistoryForward(wxCommandEvent & WXUNUSED(event))
 bool MyQueryView::IsSqlString(wxString & str)
 {
 // checks if this one is an SQL string constant
-  char word[4096];
+  char *word = new char[str.Len() * 4];
   strcpy(word, str.ToUTF8());
   int len = strlen(word);
   if (len < 2)
-    return false;
+    goto no;
   if (word[0] == '\'' && word[len - 1] == '\'')
-    return true;
+    goto yes;
   if (word[0] == '"' && word[len - 1] == '"')
-    return true;
+    goto yes;
+no:
+  delete[]word;
   return false;
+yes:
+  delete[]word;
+  return true;
 }
 
 bool MyQueryView::IsSqlNumber(wxString & str)
@@ -412,6 +429,10 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return false;
   if (str.CmpNoCase(wxT("spatialite_version")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("spatialite_target_cpu")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("freexl_version")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("geos_version")) == 0)
     return true;
   if (str.CmpNoCase(wxT("proj4_version")) == 0)
@@ -442,6 +463,25 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("hasLibXML2")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("hasGeoPackage")) == 0)
+    return true;
+
+  if (str.CmpNoCase(wxT("EnableGpkgAmphibiousMode")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("DisableGpkgAmphibiousMode")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetGpkgAmphibiousMode")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("EnableGpkgMode")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("DisableGpkgMode")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetGpkgMode")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SetDecimalPrecision")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetDecimalPrecision")) == 0)
+    return true;
 
   if (str.CmpNoCase(wxT("GeometryConstraints")) == 0)
     return true;
@@ -471,6 +511,8 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("DropVirtualGeometry")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("InvalidateLayerStatistics")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("UpdateLayerStatistics")) == 0)
     return true;
   if (str.CmpNoCase(wxT("GetLayerExtent")) == 0)
@@ -483,23 +525,103 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("RebuildGeometryTriggers")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("UpgradeGeometryTriggers")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("CheckSpatialIndex")) == 0)
     return true;
   if (str.CmpNoCase(wxT("RecoverSpatialIndex")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("CheckShadowedRowid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("CheckWithoutRowid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("CreateMetaCatalogTables")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("UpdateMetaCatalogStatistics")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("CreateTopologyTables")) == 0)
     return true;
   if (str.CmpNoCase(wxT("CreateStylingTables")) == 0)
     return true;
-  if (str.CmpNoCase(wxT("RegisterExternalGraphic")) == 0)
+  if (str.CmpNoCase(wxT("SE_RegisterVectorCoverage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterVectorCoverage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_SetVectorCoverageInfos")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_RegisterVectorCoverageSrid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterVectorCoverageSrid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_RegisterVectorCoverageKeyword")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterVectorCoverageKeyword")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UpdateVectorCoverageExtent")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_RegisterExternalGraphic")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterExternalGraphic")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_RegisterVectorStyle")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterVectorStyle")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_ReloadVectorStyle")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_RegisterVectorStyledLayer")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterVectorStyledLayer")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_RegisterRasterStyle")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterRasterStyle")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_ReloadRasterStyle")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_RegisterRasterStyledLayer")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterRasterStyledLayer")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_RegisterRasterCoverageSrid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterRasterCoverageSrid")) == 0)
     return true;
-  if (str.CmpNoCase(wxT("RegisterVectorStyledLayer")) == 0)
+  if (str.CmpNoCase(wxT("SE_RegisterRasterCoverageKeyword")) == 0)
     return true;
-  if (str.CmpNoCase(wxT("RegisterRasterStyledLayer")) == 0)
+  if (str.CmpNoCase(wxT("SE_UnregisterRasterCoverageKeyword")) == 0)
     return true;
-  if (str.CmpNoCase(wxT("RegisterStyledGroup")) == 0)
+  if (str.CmpNoCase(wxT("SE_UpdateRasterCoverageExtent")) == 0)
     return true;
-  if (str.CmpNoCase(wxT("SetStyledGroupInfos")) == 0)
+  if (str.CmpNoCase(wxT("SE_SetStyledGroupInfos")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterStyledGroup")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_RegisterStyledGroupRaster")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_RegisterStyledGroupVector")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_SetStyledGroupPaintOrder")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_SetStyledGroupRasterPaintOrder")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_SetStyledGroupVectorPaintOrder")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterStyledGroupRaster")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterStyledGroupVector")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterStyledGroupLayer")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_RegisterGroupStyle")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterGroupStyle")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_ReloadGroupStyle")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_RegisterStyledGroupStyle")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SE_UnregisterStyledGroupStyle")) == 0)
     return true;
   if (str.CmpNoCase(wxT("CreateIsoMetadataTables")) == 0)
     return true;
@@ -529,8 +651,102 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("MD5TotalChecksum")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("EncodeURL")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("DecodeURL")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("DirNameFromPath")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("FullFileNameFromPath")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("FileNameFromPath")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("FileExtFromPath")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_Create")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_CreateTranslate")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_CreateScale")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_CreateRotate")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_CreateXRoll")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_CreateYRoll")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_CreateZRoll")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_Translate")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_Scale")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_Rotate")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_XRoll")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_YRoll")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_ZRoll")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_Multiply")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_Transform")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_IsValid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_AsText")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_Determinant")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_IsInvertible")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ATM_Invert")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GCP_Compute")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GCP_Transform")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GCP_IsValid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GCP_AsText")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GCP2ATM")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("CreateRasterCoveragesTable")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("CreateVectorCoveragesTables")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("CloneTable")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("CheckDuplicateRows")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RemoveDuplicateRows")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ElementaryGeometries")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("DropGeoTable")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ImportSHP")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ExportSHP")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ImportDBF")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ExportDBF")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ExportKML")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ExportGeoJSON")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ImportXLS")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ImportWFS")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ImportDXF")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ImportDXFfromDir")) == 0)
+    return true;
 
   if (str.CmpNoCase(wxT("InsertEpsgSrid")) == 0)
     return true;
@@ -542,6 +758,8 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("Atan")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("Atan2")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("Ceil")) == 0)
     return true;
   if (str.CmpNoCase(wxT("Ceiling")) == 0)
@@ -604,6 +822,8 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("IsJpegBlob")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("IsJp2Blob")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("IsExifBlob")) == 0)
     return true;
   if (str.CmpNoCase(wxT("IsExifGpsBlob")) == 0)
@@ -622,6 +842,18 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("ST_Point")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("MakePointZ")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ST_PointZ")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("MakePointM")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ST_PointM")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("MakePointZM")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ST_PointZM")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("MakeLine")) == 0)
     return true;
   if (str.CmpNoCase(wxT("MakeCircle")) == 0)
@@ -926,6 +1158,14 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("ST_IsValid")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("IsValidReason")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ST_IsValidReason")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("IsValidDetail")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ST_IsValidDetail")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("Boundary")) == 0)
     return true;
   if (str.CmpNoCase(wxT("ST_Boundary")) == 0)
@@ -1048,6 +1288,14 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("ST_SetPoint")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("SetStartPoint")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ST_SetStartPoint")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SetEndPoint")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ST_SetEndPoint")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("MbrEqual")) == 0)
     return true;
   if (str.CmpNoCase(wxT("MbrDisjoint")) == 0)
@@ -1236,6 +1484,12 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("ST_CollectionExtract")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("ExtractMultiPoint")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ExtractMultiLinestring")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ExtractMultiPolygon")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("ST_Locate_Along_Measure")) == 0)
     return true;
   if (str.CmpNoCase(wxT("ST_Locate_Between_Measures")) == 0)
@@ -1316,8 +1570,40 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("ST_SnapToGrid")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("ST_Node")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SelfIntersections")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ST_SelfIntersections")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("SridFromAuthCRS")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("SridIsGeographic")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SridIsProjected")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SridHasFlippedAxes")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SridGetSpheroid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SridGetEllipsoid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SridGetPrimeMeridian")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SridGetDatum")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SridGetUnit")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SridGetProjection")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SridGetAxis_1_Name")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SridGetAxis_1_Orientation")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SridGetAxis_2_Name")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SridGetAxis_2_Orientation")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("ShiftCoords")) == 0)
     return true;
   if (str.CmpNoCase(wxT("ShiftCoordinates")) == 0)
@@ -1398,6 +1684,8 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("XB_AddParentId")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("XB_GetName")) == 0)
+    return true;
   if (str.CmpNoCase(wxT("XB_GetTitle")) == 0)
     return true;
   if (str.CmpNoCase(wxT("XB_GetAbstract")) == 0)
@@ -1418,6 +1706,441 @@ bool MyQueryView::IsSqlGeoFunction(wxString & str, char next_c)
     return true;
   if (str.CmpNoCase(wxT("XB_CacheFlush")) == 0)
     return true;
+  if (str.CmpNoCase(wxT("GEOS_GetLastWarningMsg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GEOS_GetLastErrorMsg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GEOS_GetLastAuxErrorMsg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GEOS_GetCriticalPointFromMsg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("LWGEOM_GetLastWarningMsg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("LWGEOM_GetLastErrorMsg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("MakePolygon")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ST_MakePolygon")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("LongLatToDMS")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("LongitudeFromDMS")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("LatitudeFromDMS")) == 0)
+    return true;
+  return false;
+}
+
+bool MyQueryView::IsSqlRasterFunction(wxString & str, char next_c)
+{
+// checks if this one is an SQL raster-function
+  if (next_c != '(')
+    return false;
+  if (str.CmpNoCase(wxT("rl2_version")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_target_cpu")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_none")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_deflate")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_deflate_no")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_jpeg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_png")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_fax4")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_lzma")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_lzma_no")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_charls")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_webp")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_ll_webp")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_jp2")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("rl2_has_codec_ll_jp2")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetMaxThreads")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_SetMaxThreads")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("IsValidPixel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_IsValidPixel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("IsValidRasterPalette")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_IsValidRasterPalette")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("IsValidRasterStatistics")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_IsValidRasterStatistics")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("IsValidRasterTile")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_IsValidRasterTile")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("CreateCoverage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_CreateRasterCoverage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("CopyRasterCoverage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_CopyRasterCoverage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("DeleteSection")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_DeleteSection")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("DropRasterCoverage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_DropRasterCoverage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SetRasterCoverageInfos")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_SetRasterCoverageInfos")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SetRasterCoverageDefaultBands")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_SetRasterCoverageDefaultBands")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("EnableRasterCoverageAutoNDVI")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_EnableRasterCoverageAutoNDVI")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("IsRasterCoverageAutoNdviEnabled")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_IsRasterCoverageAutoNdviEnabled")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetPaletteNumEntries")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetPaletteNumEntries")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetPaletteColorEntry")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetPaletteColorEntry")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SetPaletteColorEntry")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_SetPaletteColorEntry")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("PaletteEquals")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_PaletteEquals")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("CreatePixel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_CreatePixel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetPixelType")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetPixelType")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetPixelSampleType")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetPixelSampleType")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetPixelNumBands")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetPixelNumBands")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetPixelValue")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetPixelValue")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SetPixelValue")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_SetPixelValue")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("IsTransparentPixel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_IsTransparentPixel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("IsOpaquePixel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_IsOpaquePixel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SetTransparentPixel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_SetTransparentPixel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("SetOpaquePixel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_SetOpaquePixel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("PixelEquals")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_PixelEquals")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetRasterStatistics_NoDataPixelsCount")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetRasterStatistics_NoDataPixelsCount")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetRasterStatistics_ValidPixelsCount")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetRasterStatistics_ValidPixelsCount")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetRasterStatistics_SampleType")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetRasterStatistics_SampleType")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetRasterStatistics_BandsCount")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetRasterStatistics_BandsCount")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetBandStatistics_Min")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetBandStatistics_Min")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetBandStatistics_Max")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetBandStatistics_Max")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetBandStatistics_Avg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetBandStatistics_Avg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetBandStatistics_Var")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetBandStatistics_Var")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetBandStatistics_StdDev")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetBandStatistics_StdDev")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetBandStatistics_Histogram")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetBandStatistics_Histogram")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetBandHistogramFromImage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetBandHistogramFromImage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("Pyramidize")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_Pyramidize")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("DePyramidize")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_DePyramidize")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetMapImageFromRaster")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetMapImageFromRaster")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetMapImageFromVector")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetMapImageFromVector")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetTileImage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetTileImage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetTripleBandTileImage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetTripleBandTileImage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetMonoBandTileImage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetMonoBandTileImage")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("LoadFontFromFile")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_LoadFontFromFile")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("ExportFontToFile")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_ExportFontToFile")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("IsValidFont")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_IsValidFont")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetFontFamily")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetFontFamily")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GetFontFacename")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_GetFontFacename")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("IsFontBold")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_IsFontBold")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("IsFontItalic")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_IsFontItalic")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("LoadRaster")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_LoadRaster")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("LoadRastersFromDir")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_LoadRastersFromDir")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("LoadRasterFromWMS")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_LoadRasterFromWMS")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteGeoTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteGeoTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteTiffTfw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteTiffTfw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionGeoTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionGeoTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionTiffTfw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionTiffTfw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteJpegJgw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteJpegJgw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteJpeg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteJpeg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionJpegJgw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionJpegJgw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionJpeg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionJpeg")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteTripleBandGeoTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteTripleBandGeoTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteMonoBandGeoTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteMonoBandGeoTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteTripleBandTiffTfw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteTripleBandTiffTfw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteMonoBandTiffTfw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteMonoBandTiffTfw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteTripleBandTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteTripleBandTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteMonoBandTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteMonoBandTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionTripleBandGeoTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionTripleBandGeoTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionMonoBandGeoTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionMonoBandGeoTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionTripleBandTiffTfw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionTripleBandTiffTfw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionMonoBandTiffTfw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionMonoBandTiffTfw")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionTripleBandTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionTripleBandTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionMonoBandTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionMonoBandTiff")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteAsciiGrid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteAsciiGrid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionAsciiGrid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionAsciiGrid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteNdviAsciiGrid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteNdviAsciiGrid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("WriteSectionNdviAsciiGrid")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("RL2_WriteSectionNdviAsciiGrid")) == 0)
+    return true;
+
+  if (str.CmpNoCase(wxT("AutoGPKGStart")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("AutoGPKGStop")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("CheckGeoPackageMetaData")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgCreateBaseTables")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgInsertEpsgSRID")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgCreateTilesTable")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgCreateTilesZoomLevel")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgAddTileTriggers")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgGetNormalZoom")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgGetNormalRow")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgGetImageType")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgAddGeometryColumn")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgAddGeometryTriggers")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgAddSpatialIndex")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgMakePoint")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgMakePointZ")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgMakePointM")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("gpkgMakePointZM")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("AsGPB")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GeomFromGPB")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("IsValidGPB")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("GPKG_IsAssignable")) == 0)
+    return true;
+  if (str.CmpNoCase(wxT("CastAutomagic")) == 0)
+    return true;
   return false;
 }
 
@@ -1469,7 +2192,7 @@ void MyQueryView::DoSqlSyntaxColor()
           next_c = c;
           break;
         }
-      char word[4096];
+      char *word = new char[token.Len() * 4];
       strcpy(word, token.ToUTF8());
       if (gaiaIsReservedSqliteName(word))
         {
@@ -1495,7 +2218,12 @@ void MyQueryView::DoSqlSyntaxColor()
         {
           // setting the SQL geo-function style
           SqlCtrl->SetStyle(from, to, fnct_style);
+      } else if (IsSqlRasterFunction(token, next_c) == true)
+        {
+          // setting the SQL raster-function style
+          SqlCtrl->SetStyle(from, to, fnct_style);
         }
+      delete[]word;
     }
   if (BracketStart >= 0)
     {
diff --git a/QueryViewComposer.cpp b/QueryViewComposer.cpp
index 6abaa07..0e54c67 100644
--- a/QueryViewComposer.cpp
+++ b/QueryViewComposer.cpp
@@ -2439,6 +2439,14 @@ void ComposerMainPage::CreateControls()
                    wxSize(130, 21), count, tables,
                    wxCB_DROPDOWN | wxCB_READONLY);
   mainTblSizer->Add(Table1NameCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2);
+  wxString table;
+  if (Parent->GetCurrentlySelectedTable(table) == true)
+    {
+      // automatically selecting the current table
+      int sel = Table1NameCtrl->FindString(table);
+      if (sel != wxNOT_FOUND)
+        Table1NameCtrl->SetSelection(sel);
+    }
   wxBoxSizer *alias1Sizer = new wxBoxSizer(wxHORIZONTAL);
   mainTblSizer->Add(alias1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
   wxStaticText *aliasTbl1 = new wxStaticText(this, wxID_STATIC, wxT("&Alias:"));
diff --git a/Raster.cpp b/Raster.cpp
new file mode 100644
index 0000000..fbf6c2f
--- /dev/null
+++ b/Raster.cpp
@@ -0,0 +1,3169 @@
+/*
+/ Raster.cpp
+/ various dialog classes supporting Raster datasources
+/
+/ version 1.8, 2015 March 10
+/
+/ Author: Sandro Furieri a-furieri at lqt.it
+/
+/ Copyright (C) 2015  Alessandro Furieri
+/
+/    This program is free software: you can redistribute it and/or modify
+/    it under the terms of the GNU General Public License as published by
+/    the Free Software Foundation, either version 3 of the License, or
+/    (at your option) any later version.
+/
+/    This program is distributed in the hope that it will be useful,
+/    but WITHOUT ANY WARRANTY; without even the implied warranty of
+/    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/    GNU General Public License for more details.
+/
+/    You should have received a copy of the GNU General Public License
+/    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+/
+*/
+
+#include "Classdef.h"
+
+#include "wx/spinctrl.h"
+#include "wx/tokenzr.h"
+
+bool CreateRasterCoverageDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  SampleType = RL2_SAMPLE_UINT8;
+  PixelType = RL2_PIXEL_RGB;
+  NumBands = 3;
+  RedBand = -1;
+  GreenBand = -1;
+  BlueBand = -1;
+  NIRband = -1;
+  AutoNDVI = false;
+  Compression = RL2_COMPRESSION_NONE;
+  Quality = 100;
+  TileWidth = 512;
+  TileHeight = 512;
+  NotGeoreferenced = false;
+  Srid = -1;
+  HorzResolution = 1.0;
+  VertResolution = 1.0;
+  StrictResolution = false;
+  MixedResolutions = false;
+  InputPaths = true;
+  MD5 = true;
+  Summary = true;
+  if (wxDialog::Create(parent, wxID_ANY, wxT("Creating a new Raster Coverage"))
+      == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void CreateRasterCoverageDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Coverage Name
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *cvgLabel = new wxStaticText(this, wxID_STATIC, wxT("&Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, ID_CVG_NAME, wxT(""),
+                                       wxDefaultPosition, wxSize(600, 22));
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the Coverage Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, ID_CVG_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the Coverage Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl = new wxTextCtrl(this, ID_CVG_ABSTRACT, wxT(""),
+                                            wxDefaultPosition, wxSize(600, 60),
+                                            wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: main attributes
+  wxBoxSizer *typeSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(typeSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// fourth row, column #1: Pixel Type
+  wxString pixel[6];
+  pixel[0] = wxT("&Monochrome");
+  pixel[1] = wxT("&Palette");
+  pixel[2] = wxT("&Grayscale");
+  pixel[3] = wxT("&RGB");
+  pixel[4] = wxT("&MultiBand");
+  pixel[5] = wxT("&DataGrid");
+  wxRadioBox *pixelBox = new wxRadioBox(this, ID_CVG_PIXEL,
+                                        wxT("&Pixel Type"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 6,
+                                        pixel, 1,
+                                        wxRA_SPECIFY_COLS);
+  typeSizer->Add(pixelBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  pixelBox->SetSelection(3);
+// fourth row, column #2: Sample Type
+  wxString sample[11];
+  sample[0] = wxT("&1-BIT");
+  sample[1] = wxT("&2-BIT");
+  sample[2] = wxT("&4-BIT");
+  sample[3] = wxT("INT8");
+  sample[4] = wxT("UINT8");
+  sample[5] = wxT("INT16");
+  sample[6] = wxT("UINT16");
+  sample[7] = wxT("INT32");
+  sample[8] = wxT("UINT32");
+  sample[9] = wxT("FLOAT");
+  sample[10] = wxT("DOUBLE");
+  wxRadioBox *sampleBox = new wxRadioBox(this, ID_CVG_SAMPLE,
+                                         wxT("&Sample Type"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize, 11,
+                                         sample, 2,
+                                         wxRA_SPECIFY_COLS);
+  typeSizer->Add(sampleBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  sampleBox->SetSelection(4);
+  sampleBox->Enable(0, false);
+  sampleBox->Enable(1, false);
+  sampleBox->Enable(2, false);
+  sampleBox->Enable(3, false);
+  sampleBox->Enable(5, false);
+  sampleBox->Enable(7, false);
+  sampleBox->Enable(8, false);
+  sampleBox->Enable(9, false);
+  sampleBox->Enable(10, false);
+// fourth row, column #3a: NumBands / Compression Quality
+  wxBoxSizer *bndqtySizer = new wxBoxSizer(wxVERTICAL);
+  typeSizer->Add(bndqtySizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *bndBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  bndqtySizer->Add(bndBoxSizer, 0, wxALIGN_TOP | wxALL, 0);
+  wxStaticBox *bndBox = new wxStaticBox(this, wxID_STATIC,
+                                        wxT("Bands"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize);
+  wxBoxSizer *bndSizer = new wxStaticBoxSizer(bndBox, wxVERTICAL);
+  bndBoxSizer->Add(bndSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2);
+  wxSpinCtrl *bandCtrl = new wxSpinCtrl(this, ID_CVG_BANDS, wxEmptyString,
+                                        wxDefaultPosition, wxSize(60, 20),
+                                        wxSP_ARROW_KEYS,
+                                        1, 255, 3);
+  bandCtrl->Enable(false);
+  bndSizer->Add(bandCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// fourth row, column #3b: Compression Quality
+  bndqtySizer->AddSpacer(30);
+  wxBoxSizer *qtyBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  bndqtySizer->Add(qtyBoxSizer, 0, wxALIGN_BOTTOM | wxALL, 0);
+  wxStaticBox *qtyBox = new wxStaticBox(this, wxID_STATIC,
+                                        wxT("Quality"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize);
+  wxBoxSizer *qtySizer = new wxStaticBoxSizer(qtyBox, wxVERTICAL);
+  qtyBoxSizer->Add(qtySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2);
+  wxSpinCtrl *qualityCtrl = new wxSpinCtrl(this, ID_CVG_QUALITY, wxEmptyString,
+                                           wxDefaultPosition, wxSize(60, 20),
+                                           wxSP_ARROW_KEYS,
+                                           1, 100, 100);
+  qualityCtrl->Enable(false);
+  qtySizer->Add(qualityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// fourth row, column #4: Compression
+  wxString compression[13];
+  compression[0] = wxT("&Deflate [Zip]");
+  compression[1] = wxT("&LZMA [7zip]");
+  compression[2] = wxT("&PNG");
+  compression[3] = wxT("&JPEG");
+  compression[4] = wxT("&WebP (lossy)");
+  compression[5] = wxT("&WebP (lossless)");
+  compression[6] = wxT("&Jpeg2000 (lossy)");
+  compression[7] = wxT("&Jpeg2000 (lossless)");
+  compression[8] = wxT("&CharLS (lossless)");
+  compression[9] = wxT("&CCITT FAX4");
+  compression[10] = wxT("&Deflate-NoDelta");
+  compression[11] = wxT("&LZMA-NoDelta");
+  compression[12] = wxT("&None");
+  wxRadioBox *compressionBox = new wxRadioBox(this, ID_CVG_COMPRESSION,
+                                              wxT("&Compression Type"),
+                                              wxDefaultPosition,
+                                              wxDefaultSize, 13,
+                                              compression, 2,
+                                              wxRA_SPECIFY_COLS);
+  typeSizer->Add(compressionBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  compressionBox->SetSelection(12);
+  compressionBox->Enable(9, false);
+// fifth row: default bands and AutoNDVI
+  int spacer_sz = 30;
+  wxBoxSizer *defBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(defBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *defBox = new wxStaticBox(this, wxID_STATIC,
+                                        wxT("Default bands selection"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize);
+  wxBoxSizer *defSizer = new wxStaticBoxSizer(defBox, wxVERTICAL);
+  defBoxSizer->Add(defSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *defbdsSizer = new wxBoxSizer(wxHORIZONTAL);
+  defSizer->Add(defbdsSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *redLabel = new wxStaticText(this, wxID_STATIC,
+                                            wxT("Red:"));
+  defbdsSizer->Add(redLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+  wxSpinCtrl *redCtrl = new wxSpinCtrl(this, ID_CVG_RED, wxEmptyString,
+                                       wxDefaultPosition, wxSize(60, 20),
+                                       wxSP_ARROW_KEYS, -1, -1);
+  RedBand = -1;
+  redCtrl->SetValue(RedBand);
+  redCtrl->Enable(false);
+  defbdsSizer->Add(redCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+  defbdsSizer->AddSpacer(spacer_sz);
+  wxStaticText *greenLabel = new wxStaticText(this, wxID_STATIC,
+                                              wxT("Green:"));
+  defbdsSizer->Add(greenLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+  wxSpinCtrl *greenCtrl = new wxSpinCtrl(this, ID_CVG_GREEN, wxEmptyString,
+                                         wxDefaultPosition, wxSize(60, 20),
+                                         wxSP_ARROW_KEYS, -1, -1);
+  GreenBand = -1;
+  greenCtrl->SetValue(GreenBand);
+  greenCtrl->Enable(false);
+  defbdsSizer->Add(greenCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+  defbdsSizer->AddSpacer(spacer_sz);
+  wxStaticText *blueLabel = new wxStaticText(this, wxID_STATIC,
+                                             wxT("Blue:"));
+  defbdsSizer->Add(blueLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+  wxSpinCtrl *blueCtrl = new wxSpinCtrl(this, ID_CVG_BLUE, wxEmptyString,
+                                        wxDefaultPosition, wxSize(60, 20),
+                                        wxSP_ARROW_KEYS, -1, -1);
+  BlueBand = -1;
+  blueCtrl->SetValue(BlueBand);
+  blueCtrl->Enable(false);
+  defbdsSizer->Add(blueCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+  defbdsSizer->AddSpacer(spacer_sz);
+  wxStaticText *nirLabel = new wxStaticText(this, wxID_STATIC,
+                                            wxT("NIR:"));
+  defbdsSizer->Add(nirLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+  wxSpinCtrl *nirCtrl = new wxSpinCtrl(this, ID_CVG_NIR, wxEmptyString,
+                                       wxDefaultPosition, wxSize(60, 20),
+                                       wxSP_ARROW_KEYS, -1, -1);
+  NIRband = -1;
+  nirCtrl->SetValue(NIRband);
+  nirCtrl->Enable(false);
+  defbdsSizer->Add(nirCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+  defbdsSizer->AddSpacer(spacer_sz);
+  wxCheckBox *autoNDVIctrl = new wxCheckBox(this, ID_CVG_AUTO_NDVI,
+                                            wxT("Auto NDVI"),
+                                            wxDefaultPosition, wxDefaultSize);
+  autoNDVIctrl->SetValue(false);
+  autoNDVIctrl->Enable(false);
+  defbdsSizer->Add(autoNDVIctrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+// fifth row: NO-DATA value Name
+  wxBoxSizer *ndBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(ndBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *ndBox = new wxStaticBox(this, wxID_STATIC,
+                                       wxT("NO-DATA Pixel"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize);
+  wxBoxSizer *ndSizer = new wxStaticBoxSizer(ndBox, wxVERTICAL);
+  ndBoxSizer->Add(ndSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *nodataSizer = new wxBoxSizer(wxHORIZONTAL);
+  ndSizer->Add(nodataSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxTextCtrl *nodataCtrl = new wxTextCtrl(this, ID_CVG_NODATA, wxT(""),
+                                          wxDefaultPosition, wxSize(200, 22));
+  nodataSizer->Add(nodataCtrl, 0, wxALIGN_RIGHT | wxALL, 1);
+  wxStaticText *nodataLabel = new wxStaticText(this, wxID_STATIC,
+                                               wxT
+                                               ("         (list of comma-separated sample values) e.g.: "));
+  nodataSizer->Add(nodataLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+  wxStaticText *nodata2Label =
+    new wxStaticText(this, wxID_STATIC, wxT("255,255,255  "));
+  nodata2Label->SetForegroundColour(wxColour(255, 0, 0));
+  nodataSizer->Add(nodata2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+// sixth row: other attributes
+  wxBoxSizer *mixSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(mixSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// sixth row, column #1: Tile Size
+  wxBoxSizer *tileBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  mixSizer->Add(tileBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *tileBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Tile Size"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *tileSizer = new wxStaticBoxSizer(tileBox, wxVERTICAL);
+  tileBoxSizer->Add(tileSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *tileWSizer = new wxBoxSizer(wxHORIZONTAL);
+  tileSizer->Add(tileWSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2);
+  wxStaticText *tileWLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Width:"));
+  tileWSizer->Add(tileWLabel, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxSpinCtrl *widthCtrl = new wxSpinCtrl(this, ID_CVG_WIDTH, wxEmptyString,
+                                         wxDefaultPosition, wxSize(60, 20),
+                                         wxSP_ARROW_KEYS,
+                                         256, 1024, 512);
+  tileWSizer->Add(widthCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *tileXSizer = new wxBoxSizer(wxHORIZONTAL);
+  tileSizer->Add(tileXSizer, 0, wxALIGN_RIGHT | wxALL, 2);
+  wxCheckBox *squareTileCtrl = new wxCheckBox(this, ID_CVG_SQTILE,
+                                              wxT("square tile"),
+                                              wxDefaultPosition, wxDefaultSize);
+  squareTileCtrl->SetValue(true);
+  tileXSizer->Add(squareTileCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *tileHSizer = new wxBoxSizer(wxHORIZONTAL);
+  tileSizer->Add(tileHSizer, 0, wxALIGN_RIGHT | wxALL, 2);
+  wxStaticText *tileHLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Height:"));
+  tileHSizer->Add(tileHLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSpinCtrl *heightCtrl = new wxSpinCtrl(this, ID_CVG_HEIGHT, wxEmptyString,
+                                          wxDefaultPosition, wxSize(60, 20),
+                                          wxSP_ARROW_KEYS,
+                                          256, 1024, 512);
+  heightCtrl->Enable(false);
+  tileHSizer->Add(heightCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// sixth row, column #2: SRID
+  wxBoxSizer *sridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  mixSizer->Add(sridBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *sridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Georeferencing"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *geoSizer = new wxStaticBoxSizer(sridBox, wxVERTICAL);
+  sridBoxSizer->Add(geoSizer, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxBoxSizer *norefSizer = new wxBoxSizer(wxHORIZONTAL);
+  geoSizer->Add(norefSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2);
+  wxCheckBox *norefCtrl = new wxCheckBox(this, ID_CVG_NOREF,
+                                         wxT("none"),
+                                         wxDefaultPosition, wxDefaultSize);
+  norefCtrl->SetValue(false);
+  norefSizer->Add(norefCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *sridSizer = new wxBoxSizer(wxHORIZONTAL);
+  geoSizer->Add(sridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2);
+  wxStaticText *sridLabel = new wxStaticText(this, wxID_STATIC, wxT("&SRID:"));
+  sridSizer->Add(sridLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  int srid = 0;
+  wxSpinCtrl *sridCtrl = new wxSpinCtrl(this, ID_CVG_SRID, wxEmptyString,
+                                        wxDefaultPosition, wxSize(80, 20),
+                                        wxSP_ARROW_KEYS,
+                                        -1, 1000000, srid);
+  sridSizer->Add(sridCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// sixth row, column #3: Pixel Resolution
+  wxBoxSizer *resBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  mixSizer->Add(resBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *resBox = new wxStaticBox(this, wxID_STATIC,
+                                        wxT("Pixel Resolution"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize);
+  wxBoxSizer *resSizer = new wxStaticBoxSizer(resBox, wxVERTICAL);
+  resBoxSizer->Add(resSizer, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxBoxSizer *resHSizer = new wxBoxSizer(wxHORIZONTAL);
+  resSizer->Add(resHSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2);
+  wxStaticText *resHLabel = new wxStaticText(this, wxID_STATIC, wxT("&Horz:"));
+  resHSizer->Add(resHLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *horzCtrl = new wxTextCtrl(this, ID_CVG_HORZ_RES, wxT("1.0"),
+                                        wxDefaultPosition, wxSize(80, 22));
+  resHSizer->Add(horzCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *resXSizer = new wxBoxSizer(wxHORIZONTAL);
+  resSizer->Add(resXSizer, 0, wxALIGN_RIGHT | wxALL, 2);
+  wxCheckBox *sameResCtrl = new wxCheckBox(this, ID_CVG_SAME_RES,
+                                           wxT("same resolution"),
+                                           wxDefaultPosition, wxDefaultSize);
+  sameResCtrl->SetValue(true);
+  resXSizer->Add(sameResCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *resVSizer = new wxBoxSizer(wxHORIZONTAL);
+  resSizer->Add(resVSizer, 0, wxALIGN_RIGHT | wxALL, 2);
+  wxStaticText *resVLabel = new wxStaticText(this, wxID_STATIC, wxT("&Vert:"));
+  resVSizer->Add(resVLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *vertCtrl = new wxTextCtrl(this, ID_CVG_VERT_RES, wxT("1.0"),
+                                        wxDefaultPosition, wxSize(80, 22));
+  vertCtrl->Enable(false);
+  resVSizer->Add(vertCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// sixth row, column #4: Policies
+  mixSizer->AddSpacer(50);
+  wxBoxSizer *polBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  mixSizer->Add(polBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *polBox = new wxStaticBox(this, wxID_STATIC,
+                                        wxT("Policies"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize);
+  wxBoxSizer *polSizer = new wxStaticBoxSizer(polBox, wxVERTICAL);
+  polBoxSizer->Add(polSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxCheckBox *strictCtrl = new wxCheckBox(this, ID_CVG_STRICT_RES,
+                                          wxT("Strict Resolution"),
+                                          wxDefaultPosition, wxDefaultSize);
+  strictCtrl->SetValue(false);
+  polSizer->Add(strictCtrl, 0, wxALIGN_LEFT | wxALL, 2);
+  wxCheckBox *mixedCtrl = new wxCheckBox(this, ID_CVG_MIXED_RES,
+                                         wxT("Mixed Resolutions"),
+                                         wxDefaultPosition, wxDefaultSize);
+  mixedCtrl->SetValue(false);
+  polSizer->Add(mixedCtrl, 0, wxALIGN_LEFT | wxALL, 2);
+  wxCheckBox *pathsCtrl = new wxCheckBox(this, ID_CVG_PATHS,
+                                         wxT("Input Paths"),
+                                         wxDefaultPosition, wxDefaultSize);
+  pathsCtrl->SetValue(true);
+  polSizer->Add(pathsCtrl, 0, wxALIGN_LEFT | wxALL, 2);
+  wxCheckBox *md5Ctrl = new wxCheckBox(this, ID_CVG_MD5,
+                                       wxT("MD5 Checksum"),
+                                       wxDefaultPosition, wxDefaultSize);
+  md5Ctrl->SetValue(true);
+  polSizer->Add(md5Ctrl, 0, wxALIGN_LEFT | wxALL, 2);
+  wxCheckBox *summaryCtrl = new wxCheckBox(this, ID_CVG_SUMMARY,
+                                           wxT("XML Summary"),
+                                           wxDefaultPosition, wxDefaultSize);
+  summaryCtrl->SetValue(true);
+  polSizer->Add(summaryCtrl, 0, wxALIGN_LEFT | wxALL, 2);
+
+// OK - CANCEL buttons
+  wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&OK"));
+  okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel"));
+  okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & CreateRasterCoverageDialog::OnOk);
+  Connect(ID_CVG_PIXEL, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) & CreateRasterCoverageDialog::OnPixelChanged);
+  Connect(ID_CVG_SAMPLE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnSampleChanged);
+  Connect(ID_CVG_COMPRESSION, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnCompressionChanged);
+  Connect(ID_CVG_BANDS, wxEVT_COMMAND_SPINCTRL_UPDATED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnNumBandsChanged);
+  Connect(ID_CVG_BANDS, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnNumBandsChanged);
+  Connect(ID_CVG_RED, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnRedBandChanged);
+  Connect(ID_CVG_GREEN, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnGreenBandChanged);
+  Connect(ID_CVG_BLUE, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnBlueBandChanged);
+  Connect(ID_CVG_NIR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnNIRbandChanged);
+  Connect(ID_CVG_AUTO_NDVI, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnAutoNDVIchanged);
+  Connect(ID_CVG_SQTILE, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnSquareTileChanged);
+  Connect(ID_CVG_WIDTH, wxEVT_COMMAND_SPINCTRL_UPDATED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnTileWidthChanged);
+  Connect(ID_CVG_WIDTH, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnTileWidthChanged);
+  Connect(ID_CVG_HEIGHT, wxEVT_COMMAND_SPINCTRL_UPDATED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnTileHeightChanged);
+  Connect(ID_CVG_HEIGHT, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnTileHeightChanged);
+  Connect(ID_CVG_NOREF, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnNoGeorefChanged);
+  Connect(ID_CVG_SAME_RES, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnSameResChanged);
+  Connect(ID_CVG_HORZ_RES, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnHorzResChanged);
+  Connect(ID_CVG_STRICT_RES, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnStrictChanged);
+  Connect(ID_CVG_MIXED_RES, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) & CreateRasterCoverageDialog::OnMixedChanged);
+  Connect(ID_CVG_PATHS, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) & CreateRasterCoverageDialog::OnPathsChanged);
+  Connect(ID_CVG_MD5, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) & CreateRasterCoverageDialog::OnMD5Changed);
+  Connect(ID_CVG_SUMMARY, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          CreateRasterCoverageDialog::OnSummaryChanged);
+}
+
+void CreateRasterCoverageDialog::
+OnPixelChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Pixel Type selection changed
+//
+  bool is_8_bit = false;
+  bool is_16_bit = false;
+  unsigned char num_bands;
+  wxRadioBox *pixelCtrl = (wxRadioBox *) FindWindow(ID_CVG_PIXEL);
+  wxRadioBox *sampleCtrl = (wxRadioBox *) FindWindow(ID_CVG_SAMPLE);
+  wxRadioBox *compressionCtrl = (wxRadioBox *) FindWindow(ID_CVG_COMPRESSION);
+  wxSpinCtrl *bandCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_BANDS);
+  wxSpinCtrl *redBand = (wxSpinCtrl *) FindWindow(ID_CVG_RED);
+  wxSpinCtrl *greenBand = (wxSpinCtrl *) FindWindow(ID_CVG_GREEN);
+  wxSpinCtrl *blueBand = (wxSpinCtrl *) FindWindow(ID_CVG_BLUE);
+  wxSpinCtrl *nirBand = (wxSpinCtrl *) FindWindow(ID_CVG_NIR);
+  wxCheckBox *autoNDVIctrl = (wxCheckBox *) FindWindow(ID_CVG_AUTO_NDVI);
+  switch (pixelCtrl->GetSelection())
+    {
+      case 0:
+        PixelType = RL2_PIXEL_MONOCHROME;
+        break;
+      case 1:
+        PixelType = RL2_PIXEL_PALETTE;
+        break;
+      case 2:
+        PixelType = RL2_PIXEL_GRAYSCALE;
+        break;
+      case 3:
+        PixelType = RL2_PIXEL_RGB;
+        break;
+      case 4:
+        PixelType = RL2_PIXEL_MULTIBAND;
+        break;
+      case 5:
+        PixelType = RL2_PIXEL_DATAGRID;
+        break;
+    };
+  if (sampleCtrl->GetSelection() == 4)
+    is_8_bit = true;
+  if (sampleCtrl->GetSelection() == 6)
+    is_16_bit = true;
+  num_bands = bandCtrl->GetValue();
+  switch (PixelType)
+    {
+      case RL2_PIXEL_MONOCHROME:
+        sampleCtrl->Enable(0, true);
+        sampleCtrl->Enable(1, false);
+        sampleCtrl->Enable(2, false);
+        sampleCtrl->Enable(3, false);
+        sampleCtrl->Enable(4, false);
+        sampleCtrl->Enable(5, false);
+        sampleCtrl->Enable(6, false);
+        sampleCtrl->Enable(7, false);
+        sampleCtrl->Enable(8, false);
+        sampleCtrl->Enable(9, false);
+        sampleCtrl->Enable(10, false);
+        sampleCtrl->SetSelection(0);
+        bandCtrl->SetValue(1);
+        bandCtrl->Enable(false);
+        RedBand = -1;
+        GreenBand = -1;
+        BlueBand = -1;
+        NIRband = -1;
+        AutoNDVI = false;
+        redBand->SetValue(-1);
+        redBand->Enable(false);
+        greenBand->SetValue(-1);
+        greenBand->Enable(false);
+        blueBand->SetValue(-1);
+        blueBand->Enable(false);
+        nirBand->SetValue(-1);
+        nirBand->Enable(false);
+        autoNDVIctrl->SetValue(false);
+        autoNDVIctrl->Enable(false);
+        compressionCtrl->Enable(0, false);
+        compressionCtrl->Enable(1, false);
+        compressionCtrl->Enable(2, true);
+        compressionCtrl->Enable(3, false);
+        compressionCtrl->Enable(4, false);
+        compressionCtrl->Enable(5, false);
+        compressionCtrl->Enable(6, false);
+        compressionCtrl->Enable(7, false);
+        compressionCtrl->Enable(8, false);
+        compressionCtrl->Enable(9, true);
+        compressionCtrl->Enable(10, false);
+        compressionCtrl->Enable(11, false);
+        compressionCtrl->Enable(12, true);
+        if (compressionCtrl->GetSelection() == 12
+            || compressionCtrl->GetSelection() == 2
+            || compressionCtrl->GetSelection() == 9)
+          ;
+        else
+          compressionCtrl->SetSelection(9);
+        break;
+      case RL2_PIXEL_PALETTE:
+        sampleCtrl->Enable(0, true);
+        sampleCtrl->Enable(1, true);
+        sampleCtrl->Enable(2, true);
+        sampleCtrl->Enable(3, false);
+        sampleCtrl->Enable(4, true);
+        sampleCtrl->Enable(5, false);
+        sampleCtrl->Enable(6, false);
+        sampleCtrl->Enable(7, false);
+        sampleCtrl->Enable(8, false);
+        sampleCtrl->Enable(9, false);
+        sampleCtrl->Enable(10, false);
+        if (sampleCtrl->GetSelection() == 0 || sampleCtrl->GetSelection() == 1
+            || sampleCtrl->GetSelection() == 2
+            || sampleCtrl->GetSelection() == 4)
+          ;
+        else
+          sampleCtrl->SetSelection(4);
+        bandCtrl->SetValue(1);
+        bandCtrl->Enable(false);
+        RedBand = -1;
+        GreenBand = -1;
+        BlueBand = -1;
+        NIRband = -1;
+        AutoNDVI = false;
+        redBand->SetValue(-1);
+        redBand->Enable(false);
+        greenBand->SetValue(-1);
+        greenBand->Enable(false);
+        blueBand->SetValue(-1);
+        blueBand->Enable(false);
+        nirBand->SetValue(-1);
+        nirBand->Enable(false);
+        autoNDVIctrl->SetValue(false);
+        autoNDVIctrl->Enable(false);
+        compressionCtrl->Enable(0, false);
+        compressionCtrl->Enable(1, false);
+        compressionCtrl->Enable(2, true);
+        compressionCtrl->Enable(3, false);
+        compressionCtrl->Enable(4, false);
+        compressionCtrl->Enable(5, false);
+        compressionCtrl->Enable(6, false);
+        compressionCtrl->Enable(7, false);
+        compressionCtrl->Enable(8, false);
+        compressionCtrl->Enable(9, false);
+        compressionCtrl->Enable(10, false);
+        compressionCtrl->Enable(11, false);
+        compressionCtrl->Enable(12, true);
+        if (compressionCtrl->GetSelection() == 12
+            || compressionCtrl->GetSelection() == 2)
+          ;
+        else
+          compressionCtrl->SetSelection(2);
+        break;
+      case RL2_PIXEL_GRAYSCALE:
+        sampleCtrl->Enable(0, false);
+        sampleCtrl->Enable(1, true);
+        sampleCtrl->Enable(2, true);
+        sampleCtrl->Enable(3, false);
+        sampleCtrl->Enable(4, true);
+        sampleCtrl->Enable(5, false);
+        sampleCtrl->Enable(6, false);
+        sampleCtrl->Enable(7, false);
+        sampleCtrl->Enable(8, false);
+        sampleCtrl->Enable(9, false);
+        sampleCtrl->Enable(10, false);
+        if (sampleCtrl->GetSelection() == 1 || sampleCtrl->GetSelection() == 2
+            || sampleCtrl->GetSelection() == 4)
+          ;
+        else
+          sampleCtrl->SetSelection(4);
+        bandCtrl->SetValue(1);
+        bandCtrl->Enable(false);
+        RedBand = -1;
+        GreenBand = -1;
+        BlueBand = -1;
+        NIRband = -1;
+        AutoNDVI = false;
+        redBand->SetValue(-1);
+        redBand->Enable(false);
+        greenBand->SetValue(-1);
+        greenBand->Enable(false);
+        blueBand->SetValue(-1);
+        blueBand->Enable(false);
+        nirBand->SetValue(-1);
+        nirBand->Enable(false);
+        autoNDVIctrl->SetValue(false);
+        autoNDVIctrl->Enable(false);
+        compressionCtrl->Enable(0, true);
+        compressionCtrl->Enable(1, true);
+        compressionCtrl->Enable(2, true);
+        compressionCtrl->Enable(3, true);
+        compressionCtrl->Enable(4, true);
+        compressionCtrl->Enable(5, true);
+        compressionCtrl->Enable(6, true);
+        compressionCtrl->Enable(7, true);
+        compressionCtrl->Enable(8, true);
+        compressionCtrl->Enable(9, false);
+        compressionCtrl->Enable(10, true);
+        compressionCtrl->Enable(11, true);
+        compressionCtrl->Enable(12, true);
+        if (compressionCtrl->GetSelection() == 9)
+          compressionCtrl->SetSelection(0);
+        break;
+      case RL2_PIXEL_RGB:
+        sampleCtrl->Enable(0, false);
+        sampleCtrl->Enable(1, false);
+        sampleCtrl->Enable(2, false);
+        sampleCtrl->Enable(3, false);
+        sampleCtrl->Enable(4, true);
+        sampleCtrl->Enable(5, false);
+        sampleCtrl->Enable(6, true);
+        sampleCtrl->Enable(7, false);
+        sampleCtrl->Enable(8, false);
+        sampleCtrl->Enable(9, false);
+        sampleCtrl->Enable(10, false);
+        if (sampleCtrl->GetSelection() == 4 || sampleCtrl->GetSelection() == 6)
+          ;
+        else
+          sampleCtrl->SetSelection(4);
+        bandCtrl->SetValue(3);
+        bandCtrl->Enable(false);
+        RedBand = -1;
+        GreenBand = -1;
+        BlueBand = -1;
+        NIRband = -1;
+        AutoNDVI = false;
+        redBand->SetValue(-1);
+        redBand->Enable(false);
+        greenBand->SetValue(-1);
+        greenBand->Enable(false);
+        blueBand->SetValue(-1);
+        blueBand->Enable(false);
+        nirBand->SetValue(-1);
+        nirBand->Enable(false);
+        autoNDVIctrl->SetValue(false);
+        autoNDVIctrl->Enable(false);
+        compressionCtrl->Enable(0, true);
+        compressionCtrl->Enable(1, true);
+        compressionCtrl->Enable(2, true);
+        if (is_8_bit)
+          {
+            compressionCtrl->Enable(3, true);
+            compressionCtrl->Enable(4, true);
+            compressionCtrl->Enable(5, true);
+        } else
+          {
+            compressionCtrl->Enable(3, false);
+            compressionCtrl->Enable(4, false);
+            compressionCtrl->Enable(5, false);
+          }
+        compressionCtrl->Enable(6, true);
+        compressionCtrl->Enable(7, true);
+        compressionCtrl->Enable(8, true);
+        compressionCtrl->Enable(9, false);
+        compressionCtrl->Enable(10, true);
+        compressionCtrl->Enable(11, true);
+        compressionCtrl->Enable(12, true);
+        if (is_8_bit)
+          {
+            if (compressionCtrl->GetSelection() == 9)
+              compressionCtrl->SetSelection(0);
+        } else
+          {
+            if (compressionCtrl->GetSelection() == 3
+                || compressionCtrl->GetSelection() == 4
+                || compressionCtrl->GetSelection() == 5
+                || compressionCtrl->GetSelection() == 9)
+              compressionCtrl->SetSelection(0);
+          }
+        break;
+      case RL2_PIXEL_MULTIBAND:
+        sampleCtrl->Enable(0, false);
+        sampleCtrl->Enable(1, false);
+        sampleCtrl->Enable(2, false);
+        sampleCtrl->Enable(3, false);
+        sampleCtrl->Enable(4, true);
+        sampleCtrl->Enable(5, false);
+        sampleCtrl->Enable(6, true);
+        sampleCtrl->Enable(7, false);
+        sampleCtrl->Enable(8, false);
+        sampleCtrl->Enable(9, false);
+        sampleCtrl->Enable(10, false);
+        if (sampleCtrl->GetSelection() == 4 || sampleCtrl->GetSelection() == 6)
+          ;
+        else
+          sampleCtrl->SetSelection(4);
+        bandCtrl->Enable(true);
+        if (num_bands == 3 || num_bands == 4)
+          {
+            compressionCtrl->Enable(0, true);
+            compressionCtrl->Enable(1, true);
+            compressionCtrl->Enable(2, true);
+            compressionCtrl->Enable(3, false);
+            if (is_8_bit)
+              {
+                compressionCtrl->Enable(4, true);
+                compressionCtrl->Enable(5, true);
+            } else
+              {
+                compressionCtrl->Enable(4, false);
+                compressionCtrl->Enable(5, false);
+              }
+            compressionCtrl->Enable(6, true);
+            compressionCtrl->Enable(7, true);
+            compressionCtrl->Enable(8, true);
+            compressionCtrl->Enable(9, false);
+            compressionCtrl->Enable(10, true);
+            compressionCtrl->Enable(11, true);
+            compressionCtrl->Enable(12, true);
+            if (is_8_bit)
+              {
+                if (compressionCtrl->GetSelection() == 3
+                    || compressionCtrl->GetSelection() == 9)
+                  compressionCtrl->SetSelection(0);
+            } else
+              {
+                if (compressionCtrl->GetSelection() == 3
+                    || compressionCtrl->GetSelection() == 4
+                    || compressionCtrl->GetSelection() == 5
+                    || compressionCtrl->GetSelection() == 9)
+                  compressionCtrl->SetSelection(0);
+              }
+        } else
+          {
+            compressionCtrl->Enable(0, true);
+            compressionCtrl->Enable(1, true);
+            compressionCtrl->Enable(2, false);
+            compressionCtrl->Enable(3, false);
+            compressionCtrl->Enable(4, false);
+            compressionCtrl->Enable(5, false);
+            compressionCtrl->Enable(6, false);
+            compressionCtrl->Enable(7, false);
+            compressionCtrl->Enable(8, false);
+            compressionCtrl->Enable(9, false);
+            compressionCtrl->Enable(10, true);
+            compressionCtrl->Enable(11, true);
+            compressionCtrl->Enable(12, true);
+            if (compressionCtrl->GetSelection() == 12
+                || compressionCtrl->GetSelection() == 0
+                || compressionCtrl->GetSelection() == 1)
+              ;
+            else
+              compressionCtrl->SetSelection(0);
+          }
+        redBand->SetRange(-1, num_bands - 1);
+        redBand->SetValue(-1);
+        RedBand = -1;
+        redBand->Enable(true);
+        greenBand->SetRange(-1, num_bands - 1);
+        greenBand->SetValue(-1);
+        GreenBand = -1;
+        greenBand->Enable(true);
+        blueBand->SetRange(-1, num_bands - 1);
+        blueBand->SetValue(-1);
+        BlueBand = -1;
+        blueBand->Enable(true);
+        nirBand->SetRange(-1, num_bands - 1);
+        nirBand->SetValue(-1);
+        NIRband = -1;
+        nirBand->Enable(true);
+        autoNDVIctrl->SetValue(false);
+        autoNDVIctrl->Enable(true);
+        break;
+      case RL2_PIXEL_DATAGRID:
+        sampleCtrl->Enable(0, false);
+        sampleCtrl->Enable(1, false);
+        sampleCtrl->Enable(2, false);
+        sampleCtrl->Enable(3, true);
+        sampleCtrl->Enable(4, true);
+        sampleCtrl->Enable(5, true);
+        sampleCtrl->Enable(6, true);
+        sampleCtrl->Enable(7, true);
+        sampleCtrl->Enable(8, true);
+        sampleCtrl->Enable(9, true);
+        sampleCtrl->Enable(10, true);
+        if (sampleCtrl->GetSelection() == 0 || sampleCtrl->GetSelection() == 1
+            || sampleCtrl->GetSelection() == 2)
+          sampleCtrl->SetSelection(10);
+        bandCtrl->SetValue(1);
+        bandCtrl->Enable(false);
+        RedBand = -1;
+        GreenBand = -1;
+        BlueBand = -1;
+        NIRband = -1;
+        AutoNDVI = false;
+        redBand->SetValue(-1);
+        redBand->Enable(false);
+        greenBand->SetValue(-1);
+        greenBand->Enable(false);
+        blueBand->SetValue(-1);
+        blueBand->Enable(false);
+        nirBand->SetValue(-1);
+        nirBand->Enable(false);
+        autoNDVIctrl->SetValue(false);
+        autoNDVIctrl->Enable(false);
+        if (is_8_bit || is_16_bit)
+          {
+            compressionCtrl->Enable(0, true);
+            compressionCtrl->Enable(1, true);
+            compressionCtrl->Enable(2, true);
+            compressionCtrl->Enable(3, false);
+            compressionCtrl->Enable(4, false);
+            compressionCtrl->Enable(5, false);
+            compressionCtrl->Enable(6, true);
+            compressionCtrl->Enable(7, true);
+            compressionCtrl->Enable(8, true);
+            compressionCtrl->Enable(9, false);
+            compressionCtrl->Enable(10, true);
+            compressionCtrl->Enable(11, true);
+            compressionCtrl->Enable(12, true);
+            if (compressionCtrl->GetSelection() == 3
+                || compressionCtrl->GetSelection() == 4
+                || compressionCtrl->GetSelection() == 5
+                || compressionCtrl->GetSelection() == 9)
+              compressionCtrl->SetSelection(0);
+        } else
+          {
+            compressionCtrl->Enable(0, true);
+            compressionCtrl->Enable(1, true);
+            compressionCtrl->Enable(2, false);
+            compressionCtrl->Enable(3, false);
+            compressionCtrl->Enable(4, false);
+            compressionCtrl->Enable(5, false);
+            compressionCtrl->Enable(6, false);
+            compressionCtrl->Enable(7, false);
+            compressionCtrl->Enable(8, false);
+            compressionCtrl->Enable(9, false);
+            compressionCtrl->Enable(10, true);
+            compressionCtrl->Enable(11, true);
+            compressionCtrl->Enable(12, true);
+            if (compressionCtrl->GetSelection() == 12
+                || compressionCtrl->GetSelection() == 0
+                || compressionCtrl->GetSelection() == 1)
+              ;
+            else
+              compressionCtrl->SetSelection(0);
+          }
+        break;
+    };
+}
+
+void CreateRasterCoverageDialog::
+OnSampleChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Sample Type selection changed
+//
+  bool is_8_bit = false;
+  bool is_16_bit = false;
+  unsigned char num_bands;
+  wxRadioBox *pixelCtrl = (wxRadioBox *) FindWindow(ID_CVG_PIXEL);
+  wxRadioBox *sampleCtrl = (wxRadioBox *) FindWindow(ID_CVG_SAMPLE);
+  wxRadioBox *compressionCtrl = (wxRadioBox *) FindWindow(ID_CVG_COMPRESSION);
+  wxSpinCtrl *bandCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_BANDS);
+  switch (sampleCtrl->GetSelection())
+    {
+      case 0:
+        SampleType = RL2_SAMPLE_1_BIT;
+        break;
+      case 1:
+        SampleType = RL2_SAMPLE_2_BIT;
+        break;
+      case 2:
+        SampleType = RL2_SAMPLE_4_BIT;
+        break;
+      case 3:
+        SampleType = RL2_SAMPLE_INT8;
+        break;
+      case 4:
+        SampleType = RL2_SAMPLE_UINT8;
+        is_8_bit = true;
+        break;
+      case 5:
+        SampleType = RL2_SAMPLE_INT16;
+        break;
+      case 6:
+        SampleType = RL2_SAMPLE_UINT16;
+        is_16_bit = true;
+        break;
+      case 7:
+        SampleType = RL2_SAMPLE_INT32;
+        break;
+      case 8:
+        SampleType = RL2_SAMPLE_UINT32;
+        break;
+      case 9:
+        SampleType = RL2_SAMPLE_FLOAT;
+        break;
+      case 10:
+        SampleType = RL2_SAMPLE_DOUBLE;
+        break;
+    };
+  num_bands = bandCtrl->GetValue();
+  if (pixelCtrl->GetSelection() == 3)
+    {
+      // RGB pixel
+      if (is_8_bit)
+        {
+          compressionCtrl->Enable(3, true);
+          compressionCtrl->Enable(4, true);
+          compressionCtrl->Enable(5, true);
+      } else
+        {
+          compressionCtrl->Enable(3, false);
+          compressionCtrl->Enable(4, false);
+          compressionCtrl->Enable(5, false);
+        }
+      if (is_8_bit)
+        {
+          if (compressionCtrl->GetSelection() == 9)
+            compressionCtrl->SetSelection(0);
+      } else
+        {
+          if (compressionCtrl->GetSelection() == 3
+              || compressionCtrl->GetSelection() == 4
+              || compressionCtrl->GetSelection() == 5
+              || compressionCtrl->GetSelection() == 9)
+            compressionCtrl->SetSelection(0);
+        }
+    }
+  if (pixelCtrl->GetSelection() == 4)
+    {
+      // MULTIBAND pixel
+      if (num_bands == 3 || num_bands == 4)
+        {
+          compressionCtrl->Enable(2, true);
+          if (is_8_bit)
+            {
+              compressionCtrl->Enable(4, true);
+              compressionCtrl->Enable(5, true);
+          } else
+            {
+              compressionCtrl->Enable(4, false);
+              compressionCtrl->Enable(5, false);
+            }
+          compressionCtrl->Enable(6, true);
+          compressionCtrl->Enable(7, true);
+          compressionCtrl->Enable(8, true);
+          if (is_8_bit)
+            {
+              if (compressionCtrl->GetSelection() == 3
+                  || compressionCtrl->GetSelection() == 9)
+                compressionCtrl->SetSelection(0);
+          } else
+            {
+              if (compressionCtrl->GetSelection() == 3
+                  || compressionCtrl->GetSelection() == 4
+                  || compressionCtrl->GetSelection() == 5
+                  || compressionCtrl->GetSelection() == 9)
+                compressionCtrl->SetSelection(0);
+            }
+      } else
+        {
+          compressionCtrl->Enable(2, false);
+          compressionCtrl->Enable(3, false);
+          compressionCtrl->Enable(4, false);
+          compressionCtrl->Enable(5, false);
+          compressionCtrl->Enable(6, false);
+          compressionCtrl->Enable(7, false);
+          compressionCtrl->Enable(8, false);
+          if (compressionCtrl->GetSelection() == 12
+              || compressionCtrl->GetSelection() == 0
+              || compressionCtrl->GetSelection() == 1)
+            ;
+          else
+            compressionCtrl->SetSelection(0);
+        }
+    }
+  if (pixelCtrl->GetSelection() == 5)
+    {
+      // DATAGRID pixel
+      if (is_8_bit || is_16_bit)
+        {
+          compressionCtrl->Enable(0, true);
+          compressionCtrl->Enable(1, true);
+          compressionCtrl->Enable(2, true);
+          compressionCtrl->Enable(3, false);
+          compressionCtrl->Enable(4, false);
+          compressionCtrl->Enable(5, false);
+          compressionCtrl->Enable(6, true);
+          compressionCtrl->Enable(7, true);
+          compressionCtrl->Enable(8, true);
+          compressionCtrl->Enable(9, false);
+          compressionCtrl->Enable(10, true);
+          compressionCtrl->Enable(11, true);
+          compressionCtrl->Enable(12, true);
+          if (compressionCtrl->GetSelection() == 3
+              || compressionCtrl->GetSelection() == 4
+              || compressionCtrl->GetSelection() == 5
+              || compressionCtrl->GetSelection() == 9)
+            compressionCtrl->SetSelection(0);
+      } else
+        {
+          compressionCtrl->Enable(0, true);
+          compressionCtrl->Enable(1, true);
+          compressionCtrl->Enable(2, false);
+          compressionCtrl->Enable(3, false);
+          compressionCtrl->Enable(4, false);
+          compressionCtrl->Enable(5, false);
+          compressionCtrl->Enable(6, false);
+          compressionCtrl->Enable(7, false);
+          compressionCtrl->Enable(8, false);
+          compressionCtrl->Enable(9, false);
+          compressionCtrl->Enable(10, true);
+          compressionCtrl->Enable(11, true);
+          compressionCtrl->Enable(12, true);
+          if (compressionCtrl->GetSelection() == 12
+              || compressionCtrl->GetSelection() == 0
+              || compressionCtrl->GetSelection() == 1)
+            ;
+          else
+            compressionCtrl->SetSelection(0);
+        }
+    }
+}
+
+void CreateRasterCoverageDialog::
+OnCompressionChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Compression selection changed
+//
+  bool lossy = false;
+  wxRadioBox *compressionCtrl = (wxRadioBox *) FindWindow(ID_CVG_COMPRESSION);
+  wxSpinCtrl *qualityCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_QUALITY);
+  switch (compressionCtrl->GetSelection())
+    {
+      case 0:
+        Compression = RL2_COMPRESSION_DEFLATE;
+        break;
+      case 1:
+        Compression = RL2_COMPRESSION_LZMA;
+        break;
+      case 2:
+        Compression = RL2_COMPRESSION_PNG;
+        break;
+      case 3:
+        Compression = RL2_COMPRESSION_JPEG;
+        lossy = true;
+        break;
+      case 4:
+        Compression = RL2_COMPRESSION_LOSSY_WEBP;
+        lossy = true;
+        break;
+      case 5:
+        Compression = RL2_COMPRESSION_LOSSLESS_WEBP;
+        break;
+      case 6:
+        Compression = RL2_COMPRESSION_LOSSY_JP2;
+        lossy = true;
+        break;
+      case 7:
+        Compression = RL2_COMPRESSION_LOSSLESS_JP2;
+        break;
+      case 8:
+        Compression = RL2_COMPRESSION_CHARLS;
+        break;
+      case 9:
+        Compression = RL2_COMPRESSION_CCITTFAX4;
+        break;
+      case 10:
+        Compression = RL2_COMPRESSION_DEFLATE_NO;
+        break;
+      case 11:
+        Compression = RL2_COMPRESSION_LZMA_NO;
+        break;
+      case 12:
+        Compression = RL2_COMPRESSION_NONE;
+        break;
+    };
+  if (lossy)
+    {
+      if (qualityCtrl->GetValue() == 100)
+        {
+          if (Compression == RL2_COMPRESSION_LOSSY_JP2)
+            qualityCtrl->SetValue(25);
+          else
+            qualityCtrl->SetValue(80);
+        }
+      qualityCtrl->Enable(true);
+  } else
+    {
+      qualityCtrl->SetValue(100);
+      qualityCtrl->Enable(false);
+    }
+}
+
+void CreateRasterCoverageDialog::
+OnNumBandsChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// NumBands changed
+//
+  bool is_8_bit = false;
+  bool is_16_bit = false;
+  wxRadioBox *compressionCtrl = (wxRadioBox *) FindWindow(ID_CVG_COMPRESSION);
+  wxRadioBox *sampleCtrl = (wxRadioBox *) FindWindow(ID_CVG_SAMPLE);
+  wxSpinCtrl *bandsCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_BANDS);
+  wxSpinCtrl *redBand = (wxSpinCtrl *) FindWindow(ID_CVG_RED);
+  wxSpinCtrl *greenBand = (wxSpinCtrl *) FindWindow(ID_CVG_GREEN);
+  wxSpinCtrl *blueBand = (wxSpinCtrl *) FindWindow(ID_CVG_BLUE);
+  wxSpinCtrl *nirBand = (wxSpinCtrl *) FindWindow(ID_CVG_NIR);
+  unsigned char num_bands = bandsCtrl->GetValue();
+  if (sampleCtrl->GetSelection() == 4)
+    is_8_bit = true;
+  if (sampleCtrl->GetSelection() == 6)
+    is_16_bit = true;
+  redBand->SetRange(-1, num_bands - 1);
+  if (RedBand >= 0 && RedBand < num_bands)
+    redBand->SetValue(RedBand);
+  else
+    {
+      RedBand = -1;
+      redBand->SetValue(-1);
+    }
+  greenBand->SetRange(-1, num_bands - 1);
+  if (GreenBand >= 0 && GreenBand < num_bands)
+    greenBand->SetValue(GreenBand);
+  else
+    {
+      GreenBand = -1;
+      greenBand->SetValue(-1);
+    }
+  blueBand->SetRange(-1, num_bands - 1);
+  if (BlueBand >= 0 && BlueBand < num_bands)
+    blueBand->SetValue(BlueBand);
+  else
+    {
+      BlueBand = -1;
+      blueBand->SetValue(-1);
+    }
+  nirBand->SetRange(-1, num_bands - 1);
+  if (NIRband >= 0 && NIRband < num_bands)
+    nirBand->SetValue(NIRband);
+  else
+    {
+      NIRband = -1;
+      nirBand->SetValue(-1);
+    }
+  if (num_bands == 3 || num_bands == 4)
+    {
+      compressionCtrl->Enable(0, true);
+      compressionCtrl->Enable(1, true);
+      compressionCtrl->Enable(2, true);
+      compressionCtrl->Enable(3, false);
+      if (is_8_bit)
+        {
+          compressionCtrl->Enable(4, true);
+          compressionCtrl->Enable(5, true);
+      } else
+        {
+          compressionCtrl->Enable(4, false);
+          compressionCtrl->Enable(5, false);
+        }
+      compressionCtrl->Enable(6, true);
+      compressionCtrl->Enable(7, true);
+      compressionCtrl->Enable(8, true);
+      compressionCtrl->Enable(9, false);
+      compressionCtrl->Enable(10, true);
+      compressionCtrl->Enable(11, true);
+      compressionCtrl->Enable(12, true);
+      if (is_8_bit)
+        {
+          if (compressionCtrl->GetSelection() == 3
+              || compressionCtrl->GetSelection() == 9)
+            compressionCtrl->SetSelection(0);
+      } else
+        {
+          if (compressionCtrl->GetSelection() == 3
+              || compressionCtrl->GetSelection() == 4
+              || compressionCtrl->GetSelection() == 5
+              || compressionCtrl->GetSelection() == 9)
+            compressionCtrl->SetSelection(0);
+        }
+  } else
+    {
+      compressionCtrl->Enable(0, true);
+      compressionCtrl->Enable(1, true);
+      compressionCtrl->Enable(2, false);
+      compressionCtrl->Enable(3, false);
+      compressionCtrl->Enable(4, false);
+      compressionCtrl->Enable(5, false);
+      compressionCtrl->Enable(6, false);
+      compressionCtrl->Enable(7, false);
+      compressionCtrl->Enable(8, false);
+      compressionCtrl->Enable(9, false);
+      compressionCtrl->Enable(10, true);
+      compressionCtrl->Enable(11, true);
+      compressionCtrl->Enable(12, true);
+      if (compressionCtrl->GetSelection() == 12
+          || compressionCtrl->GetSelection() == 0
+          || compressionCtrl->GetSelection() == 1)
+        ;
+      else
+        compressionCtrl->SetSelection(0);
+    }
+}
+
+void CreateRasterCoverageDialog::
+OnRedBandChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// default Red Band changed
+//
+  wxSpinCtrl *redCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_RED);
+  RedBand = redCtrl->GetValue();
+}
+
+void CreateRasterCoverageDialog::
+OnGreenBandChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// default Green Band changed
+//
+  wxSpinCtrl *greenCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_GREEN);
+  GreenBand = greenCtrl->GetValue();
+}
+
+void CreateRasterCoverageDialog::
+OnBlueBandChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// default Blue Band changed
+//
+  wxSpinCtrl *blueCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_BLUE);
+  BlueBand = blueCtrl->GetValue();
+}
+
+void CreateRasterCoverageDialog::
+OnNIRbandChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// default NIR Band changed
+//
+  wxSpinCtrl *nirCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_NIR);
+  NIRband = nirCtrl->GetValue();
+}
+
+void CreateRasterCoverageDialog::
+OnAutoNDVIchanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// changed Auto NDVI (on/off): 
+//
+  wxCheckBox *autoNDVIctrl = (wxCheckBox *) FindWindow(ID_CVG_AUTO_NDVI);
+  if (autoNDVIctrl->IsChecked() == true)
+    AutoNDVI = true;
+  else
+    AutoNDVI = false;
+}
+
+void CreateRasterCoverageDialog::
+OnSquareTileChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// changed Square Tile (on/off): 
+//
+  wxCheckBox *squareCtrl = (wxCheckBox *) FindWindow(ID_CVG_SQTILE);
+  wxSpinCtrl *widthCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_WIDTH);
+  wxSpinCtrl *heightCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_HEIGHT);
+  if (squareCtrl->IsChecked() == true)
+    {
+      heightCtrl->SetValue(widthCtrl->GetValue());
+      heightCtrl->Enable(false);
+  } else
+    heightCtrl->Enable(true);
+}
+
+void CreateRasterCoverageDialog::
+OnTileWidthChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Tile Width changed
+//
+  wxCheckBox *squareCtrl = (wxCheckBox *) FindWindow(ID_CVG_SQTILE);
+  wxSpinCtrl *widthCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_WIDTH);
+  wxSpinCtrl *heightCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_HEIGHT);
+  int width = widthCtrl->GetValue();
+  if ((width % 8) != 0)
+    {
+      // ensuring to be am exact multiple of 8
+      if (width > TileWidth)
+        TileWidth = ((width / 8) + 1) * 8;
+      else
+        TileWidth = (width / 8) * 8;
+  } else
+    TileWidth = width;
+  widthCtrl->SetValue(TileWidth);
+  if (squareCtrl->IsChecked() == true)
+    {
+      TileHeight = TileWidth;
+      heightCtrl->SetValue(TileHeight);
+    }
+}
+
+void CreateRasterCoverageDialog::
+OnTileHeightChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Tile Height changed
+//
+  wxSpinCtrl *heightCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_HEIGHT);
+  int height = heightCtrl->GetValue();
+  if ((height % 8) != 0)
+    {
+      // ensuring to be an exact multiple of 8
+      if (height > TileHeight)
+        TileHeight = ((height / 8) + 1) * 8;
+      else
+        TileHeight = (height / 8) * 8;
+  } else
+    TileHeight = height;
+  heightCtrl->SetValue(TileHeight);
+}
+
+void CreateRasterCoverageDialog::
+OnNoGeorefChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// changed Not Georeferenced (on/off): 
+//
+  wxCheckBox *norefCtrl = (wxCheckBox *) FindWindow(ID_CVG_NOREF);
+  wxSpinCtrl *sridCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_SRID);
+  if (norefCtrl->IsChecked() == true)
+    {
+      sridCtrl->SetValue(-1);
+      sridCtrl->Enable(false);
+  } else
+    sridCtrl->Enable(true);
+}
+
+void CreateRasterCoverageDialog::
+OnSameResChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// changed Square Tile (on/off): 
+//
+  wxCheckBox *sameresCtrl = (wxCheckBox *) FindWindow(ID_CVG_SAME_RES);
+  wxTextCtrl *horzCtrl = (wxTextCtrl *) FindWindow(ID_CVG_HORZ_RES);
+  wxTextCtrl *vertCtrl = (wxTextCtrl *) FindWindow(ID_CVG_VERT_RES);
+  if (sameresCtrl->IsChecked() == true)
+    {
+      vertCtrl->SetValue(horzCtrl->GetValue());
+      vertCtrl->Enable(false);
+  } else
+    vertCtrl->Enable(true);
+}
+
+void CreateRasterCoverageDialog::
+OnHorzResChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// changed Horz Resolution  
+//
+  wxCheckBox *sameresCtrl = (wxCheckBox *) FindWindow(ID_CVG_SAME_RES);
+  wxTextCtrl *horzCtrl = (wxTextCtrl *) FindWindow(ID_CVG_HORZ_RES);
+  wxTextCtrl *vertCtrl = (wxTextCtrl *) FindWindow(ID_CVG_VERT_RES);
+  if (sameresCtrl->IsChecked() == true)
+    vertCtrl->SetValue(horzCtrl->GetValue());
+}
+
+void CreateRasterCoverageDialog::
+OnStrictChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// changed Mixed Resolutions (on/off): 
+//
+  wxCheckBox *strictCtrl = (wxCheckBox *) FindWindow(ID_CVG_STRICT_RES);
+  wxCheckBox *mixedCtrl = (wxCheckBox *) FindWindow(ID_CVG_MIXED_RES);
+  if (strictCtrl->IsChecked() == true)
+    StrictResolution = true;
+  else
+    StrictResolution = false;
+  if (StrictResolution)
+    mixedCtrl->SetValue(false);
+}
+
+void CreateRasterCoverageDialog::
+OnMixedChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// changed Mixed Resolutions (on/off): 
+//
+  wxCheckBox *strictCtrl = (wxCheckBox *) FindWindow(ID_CVG_STRICT_RES);
+  wxCheckBox *mixedCtrl = (wxCheckBox *) FindWindow(ID_CVG_MIXED_RES);
+  if (mixedCtrl->IsChecked() == true)
+    MixedResolutions = true;
+  else
+    MixedResolutions = false;
+  if (MixedResolutions)
+    strictCtrl->SetValue(false);
+}
+
+void CreateRasterCoverageDialog::
+OnPathsChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// changed Input Paths (on/off): 
+//
+  wxCheckBox *pathsCtrl = (wxCheckBox *) FindWindow(ID_CVG_PATHS);
+  if (pathsCtrl->IsChecked() == true)
+    InputPaths = true;
+  else
+    InputPaths = false;
+}
+
+void CreateRasterCoverageDialog::OnMD5Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// changed MD5 (on/off): 
+//
+  wxCheckBox *md5Ctrl = (wxCheckBox *) FindWindow(ID_CVG_MD5);
+  if (md5Ctrl->IsChecked() == true)
+    MD5 = true;
+  else
+    MD5 = false;
+}
+
+void CreateRasterCoverageDialog::
+OnSummaryChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// changed XML Summary (on/off): 
+//
+  wxCheckBox *summaryCtrl = (wxCheckBox *) FindWindow(ID_CVG_SUMMARY);
+  if (summaryCtrl->IsChecked() == true)
+    Summary = true;
+  else
+    Summary = false;
+}
+
+bool CreateRasterCoverageDialog::IsValidNoData(wxString & no_data, int sample,
+                                               int num_bands)
+{
+//
+// checking a NO-DATA value
+//
+  int count = 0;
+  int error = 0;
+  char dummy[128];
+  if (no_data.Len() == 0)
+    return true;
+  wxStringTokenizer tokenizer(no_data, wxT(","));
+  while (tokenizer.HasMoreTokens())
+    {
+      count++;
+      wxString token = tokenizer.GetNextToken();
+      if (sample == RL2_SAMPLE_FLOAT || sample == RL2_SAMPLE_DOUBLE)
+        {
+          double v;
+          if (token.ToDouble(&v) == false)
+            {
+              sprintf(dummy, "#%d) ", count);
+              wxMessageBox(wxT("NO-DATA - invalid sample value: ") +
+                           wxString::FromUTF8(dummy) + token,
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              error++;
+            }
+      } else
+        {
+          long v;
+          if (token.ToLong(&v) == false)
+            {
+              sprintf(dummy, "#%d) ", count);
+              wxMessageBox(wxT("NO-DATA - invalid sample value: ") +
+                           wxString::FromUTF8(dummy) + token,
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              error++;
+          } else
+            {
+              int err = 0;
+              switch (sample)
+                {
+                  case RL2_SAMPLE_1_BIT:
+                    if (v < 0 || v > 1)
+                      {
+                        sprintf(dummy, "#%d) ", count);
+                        wxMessageBox(wxT("NO-DATA - invalid sample value: ") +
+                                     wxString::FromUTF8(dummy) + token,
+                                     wxT("spatialite_gui"),
+                                     wxOK | wxICON_WARNING, this);
+                        err = 1;
+                      }
+                    break;
+                  case RL2_SAMPLE_2_BIT:
+                    if (v < 0 || v > 3)
+                      {
+                        sprintf(dummy, "#%d) ", count);
+                        wxMessageBox(wxT("NO-DATA - invalid sample value: ") +
+                                     wxString::FromUTF8(dummy) + token,
+                                     wxT("spatialite_gui"),
+                                     wxOK | wxICON_WARNING, this);
+                        err = 1;
+                      }
+                    break;
+                  case RL2_SAMPLE_4_BIT:
+                    if (v < 0 || v > 15)
+                      {
+                        sprintf(dummy, "#%d) ", count);
+                        wxMessageBox(wxT("NO-DATA - invalid sample value: ") +
+                                     wxString::FromUTF8(dummy) + token,
+                                     wxT("spatialite_gui"),
+                                     wxOK | wxICON_WARNING, this);
+                        err = 1;
+                      }
+                    break;
+                  case RL2_SAMPLE_INT8:
+                    if (v < CHAR_MIN || v > CHAR_MAX)
+                      {
+                        sprintf(dummy, "#%d) ", count);
+                        wxMessageBox(wxT("NO-DATA - invalid sample value: ") +
+                                     wxString::FromUTF8(dummy) + token,
+                                     wxT("spatialite_gui"),
+                                     wxOK | wxICON_WARNING, this);
+                        err = 1;
+                      }
+                    break;
+                  case RL2_SAMPLE_UINT8:
+                    if (v < 0 || v > UCHAR_MAX)
+                      {
+                        sprintf(dummy, "#%d) ", count);
+                        wxMessageBox(wxT("NO-DATA - invalid sample value: ") +
+                                     wxString::FromUTF8(dummy) + token,
+                                     wxT("spatialite_gui"),
+                                     wxOK | wxICON_WARNING, this);
+                        err = 1;
+                      }
+                    break;
+                  case RL2_SAMPLE_INT16:
+                    if (v < SHRT_MIN || v > SHRT_MAX)
+                      {
+                        sprintf(dummy, "#%d) ", count);
+                        wxMessageBox(wxT("NO-DATA - invalid sample value: ") +
+                                     wxString::FromUTF8(dummy) + token,
+                                     wxT("spatialite_gui"),
+                                     wxOK | wxICON_WARNING, this);
+                        err = 1;
+                      }
+                    break;
+                  case RL2_SAMPLE_UINT16:
+                    if (v < 0 || v > USHRT_MAX)
+                      {
+                        sprintf(dummy, "#%d) ", count);
+                        wxMessageBox(wxT("NO-DATA - invalid sample value: ") +
+                                     wxString::FromUTF8(dummy) + token,
+                                     wxT("spatialite_gui"),
+                                     wxOK | wxICON_WARNING, this);
+                        err = 1;
+                      }
+                    break;
+                  case RL2_SAMPLE_INT32:
+                    if (v < INT_MIN || v > INT_MAX)
+                      {
+                        sprintf(dummy, "#%d) ", count);
+                        wxMessageBox(wxT("NO-DATA - invalid sample value: ") +
+                                     wxString::FromUTF8(dummy) + token,
+                                     wxT("spatialite_gui"),
+                                     wxOK | wxICON_WARNING, this);
+                        err = 1;
+                      }
+                    break;
+                  case RL2_SAMPLE_UINT32:
+                    if (v < 0 || v > UINT_MAX)
+                      {
+                        sprintf(dummy, "#%d) ", count);
+                        wxMessageBox(wxT("NO-DATA - invalid sample value: ") +
+                                     wxString::FromUTF8(dummy) + token,
+                                     wxT("spatialite_gui"),
+                                     wxOK | wxICON_WARNING, this);
+                        err = 1;
+                      }
+                    break;
+                };
+              if (err)
+                error++;
+            }
+        }
+    }
+  if (error)
+    return false;
+  if (count != num_bands)
+    {
+      sprintf(dummy, "expected %d, found #%d", num_bands, count);
+      wxMessageBox(wxT("NO-DATA - invalid samples count: ") +
+                   wxString::FromUTF8(dummy), wxT("spatialite_gui"),
+                   wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  return true;
+}
+
+void CreateRasterCoverageDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_CVG_NAME);
+  CoverageName = nameCtrl->GetValue();
+  if (CoverageName.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the COVERAGE NAME !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (MainFrame->CoverageAlreadyExists(CoverageName) == true)
+    {
+      wxMessageBox(wxT("a Coverage name '") + CoverageName +
+                   wxT("' already exists"), wxT("spatialite_gui"),
+                   wxOK | wxICON_WARNING, this);
+      return;
+    }
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_CVG_TITLE);
+  Title = titleCtrl->GetValue();
+  if (Title.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify some TITLE !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_CVG_ABSTRACT);
+  Abstract = absCtrl->GetValue();
+  if (Abstract.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify some ABSTRACT !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  wxSpinCtrl *bandsCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_BANDS);
+  NumBands = bandsCtrl->GetValue();
+  if (PixelType == RL2_PIXEL_MULTIBAND && NumBands < 2)
+    {
+      wxMessageBox(wxT("Invalid number of Bands"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (PixelType == RL2_PIXEL_MULTIBAND)
+    {
+      if (RedBand >= 0)
+        {
+          if (RedBand >= NumBands)
+            {
+              wxMessageBox(wxT("Invalid default Red Band"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return;
+            }
+        }
+      if (GreenBand >= 0)
+        {
+          if (GreenBand >= NumBands)
+            {
+              wxMessageBox(wxT("Invalid default Green Band"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return;
+            }
+        }
+      if (BlueBand >= 0)
+        {
+          if (BlueBand >= NumBands)
+            {
+              wxMessageBox(wxT("Invalid default Blue Band"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return;
+            }
+        }
+      if (NIRband >= 0)
+        {
+          if (NIRband >= NumBands)
+            {
+              wxMessageBox(wxT("Invalid default NIR Band"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return;
+            }
+        }
+      if (RedBand == GreenBand)
+        {
+          wxMessageBox(wxT("default Red and Green are the same Band"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return;
+        }
+      if (RedBand == BlueBand)
+        {
+          wxMessageBox(wxT("default Red and Blue are the same Band"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return;
+        }
+      if (RedBand == NIRband)
+        {
+          wxMessageBox(wxT("default Red and NIR are the same Band"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return;
+        }
+      if (GreenBand == BlueBand)
+        {
+          wxMessageBox(wxT("default Green and Blue are the same Band"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return;
+        }
+      if (GreenBand == NIRband)
+        {
+          wxMessageBox(wxT("default Green and NIR are the same Band"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return;
+        }
+      if (BlueBand == NIRband)
+        {
+          wxMessageBox(wxT("default Blue and NIR are the same Band"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return;
+        }
+  } else
+    {
+      RedBand = -1;
+      GreenBand = -1;
+      BlueBand = -1;
+      NIRband = -1;
+      AutoNDVI = false;
+    }
+  wxCheckBox *norefCtrl = (wxCheckBox *) FindWindow(ID_CVG_NOREF);
+  if (norefCtrl->IsChecked() == true)
+    {
+      NotGeoreferenced = true;
+      Srid = -1;
+  } else
+    {
+      wxSpinCtrl *sridCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_SRID);
+      Srid = sridCtrl->GetValue();
+      if (Srid <= 0)
+        {
+          wxMessageBox(wxT("You must specify some SRID value !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return;
+      } else if (MainFrame->SridNotExists(Srid) == true)
+        {
+          wxMessageBox(wxT("invalid SRID value"), wxT("spatialite_gui"),
+                       wxOK | wxICON_WARNING, this);
+          return;
+        }
+    }
+  wxSpinCtrl *qtyCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_QUALITY);
+  Quality = qtyCtrl->GetValue();
+  wxSpinCtrl *widthCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_WIDTH);
+  TileWidth = widthCtrl->GetValue();
+  wxSpinCtrl *heightCtrl = (wxSpinCtrl *) FindWindow(ID_CVG_HEIGHT);
+  TileHeight = heightCtrl->GetValue();
+  wxTextCtrl *horzCtrl = (wxTextCtrl *) FindWindow(ID_CVG_HORZ_RES);
+  wxString v = horzCtrl->GetValue();
+  if (v.ToDouble(&HorzResolution) == false)
+    {
+      wxMessageBox(wxT("invalid HORIZONTAL resolution value"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (HorzResolution <= 0.0)
+    {
+      wxMessageBox(wxT("HORIZONTAL resolution should be a positive value"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  wxTextCtrl *vertCtrl = (wxTextCtrl *) FindWindow(ID_CVG_VERT_RES);
+  v = vertCtrl->GetValue();
+  if (v.ToDouble(&VertResolution) == false)
+    {
+      wxMessageBox(wxT("invalid VERTICAL resolution value"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (VertResolution <= 0.0)
+    {
+      wxMessageBox(wxT("VERTICAL resolution should be a positive value"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  wxTextCtrl *ndCtrl = (wxTextCtrl *) FindWindow(ID_CVG_NODATA);
+  NoData = ndCtrl->GetValue();
+  if (IsValidNoData(NoData, SampleType, NumBands) == false)
+    return;
+  wxCheckBox *strictCtrl = (wxCheckBox *) FindWindow(ID_CVG_STRICT_RES);
+  if (strictCtrl->IsChecked() == true)
+    StrictResolution = true;
+  else
+    StrictResolution = false;
+  wxCheckBox *mixedCtrl = (wxCheckBox *) FindWindow(ID_CVG_MIXED_RES);
+  if (mixedCtrl->IsChecked() == true)
+    MixedResolutions = true;
+  else
+    MixedResolutions = false;
+  wxCheckBox *pathsCtrl = (wxCheckBox *) FindWindow(ID_CVG_PATHS);
+  if (pathsCtrl->IsChecked() == true)
+    InputPaths = true;
+  else
+    InputPaths = false;
+  wxCheckBox *md5Ctrl = (wxCheckBox *) FindWindow(ID_CVG_MD5);
+  if (md5Ctrl->IsChecked() == true)
+    MD5 = true;
+  else
+    MD5 = false;
+  wxCheckBox *summaryCtrl = (wxCheckBox *) FindWindow(ID_CVG_SUMMARY);
+  if (summaryCtrl->IsChecked() == true)
+    Summary = true;
+  else
+    Summary = false;
+  wxDialog::EndModal(wxID_OK);
+  return;
+end:
+  wxDialog::EndModal(wxID_CANCEL);
+}
+
+bool ImportRasterDialog::Create(MyFrame * parent, wxString & coverage,
+                                wxArrayString & paths, wxString & path,
+                                wxString & title, wxString & abstract,
+                                wxString & sample, wxString & pixel,
+                                wxString & compression, int srid)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  CoverageName = coverage;
+  Paths = paths;
+  Path = path;
+  Title = title;
+  Abstract = abstract;
+  Sample = sample;
+  Pixel = pixel;
+  Compression = compression;
+  Srid = srid;
+  ForceSrid = false;
+  WithWorldFile = false;
+  Pyramidize = false;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Loading external files into a Raster Coverage")) ==
+      false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void ImportRasterDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Coverage Name
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *cvgLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("Coverage &Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, wxID_ANY, CoverageName,
+                                       wxDefaultPosition, wxSize(600, 22),
+                                       wxTE_READONLY);
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the Coverage Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, wxID_ANY, Title,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the Coverage Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl = new wxTextCtrl(this, wxID_ANY, Abstract,
+                                            wxDefaultPosition, wxSize(600, 60),
+                                            wxTE_MULTILINE | wxTE_READONLY);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the Sample Type
+  wxBoxSizer *sampleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(sampleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *sampleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Sample Type:"));
+  sampleSizer->Add(sampleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *sampleCtrl = new wxTextCtrl(this, wxID_ANY, Sample,
+                                          wxDefaultPosition, wxSize(600, 22),
+                                          wxTE_READONLY);
+  sampleSizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fifth row: the Pixel Type
+  wxBoxSizer *pixelSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(pixelSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *pixelLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Pixel Type:"));
+  pixelSizer->Add(pixelLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *pixelCtrl = new wxTextCtrl(this, wxID_ANY, Pixel,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  pixelSizer->Add(pixelCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// sixth row: the Compression Type
+  wxBoxSizer *comprSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(comprSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *comprLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Compression:"));
+  comprSizer->Add(comprLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *comprCtrl = new wxTextCtrl(this, wxID_ANY, Compression,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  comprSizer->Add(comprCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// seventh row: files to be imported
+  wxBoxSizer *fileSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(fileSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *fileLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("Import &File(s):"));
+  fileSizer->Add(fileLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *filesCtrl = new wxTextCtrl(this, wxID_ANY, Path,
+                                         wxDefaultPosition, wxSize(600, 60),
+                                         wxTE_MULTILINE | wxTE_READONLY);
+  fileSizer->Add(filesCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// eighth  row: Import Options
+  int space_sz = 35;
+  wxBoxSizer *optBoxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(optBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *optBox = new wxStaticBox(this, wxID_STATIC,
+                                        wxT("Import Options"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize);
+  wxBoxSizer *optSizer = new wxStaticBoxSizer(optBox, wxHORIZONTAL);
+  optBoxSizer->Add(optSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *sridSizer = new wxBoxSizer(wxHORIZONTAL);
+  optSizer->Add(sridSizer, 0, wxALIGN_LEFT | wxALL, 0);
+  optSizer->AddSpacer(space_sz);
+  wxCheckBox *forceSridCtrl = new wxCheckBox(this, ID_LOAD_FORCE_SRID,
+                                             wxT("Forced SRID value"),
+                                             wxDefaultPosition, wxDefaultSize);
+  forceSridCtrl->SetValue(false);
+  sridSizer->Add(forceSridCtrl, 0, wxALIGN_LEFT | wxALL, 5);
+  wxSpinCtrl *sridCtrl = new wxSpinCtrl(this, ID_LOAD_SRID, wxEmptyString,
+                                        wxDefaultPosition, wxSize(60, 20),
+                                        wxSP_ARROW_KEYS, -1, 1000000, Srid);
+  sridCtrl->Enable(false);
+  sridSizer->Add(sridCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
+  wxCheckBox *worldCtrl = new wxCheckBox(this, ID_LOAD_WITH_WORLDFILE,
+                                         wxT("With WorldFile support"),
+                                         wxDefaultPosition, wxDefaultSize);
+  worldCtrl->SetValue(false);
+  optSizer->Add(worldCtrl, 0, wxALIGN_LEFT | wxALL, 5);
+  optSizer->AddSpacer(space_sz);
+  wxCheckBox *pyrCtrl = new wxCheckBox(this, ID_LOAD_PYRAMIDIZE,
+                                       wxT
+                                       ("Immediately build Section Pyramids"),
+                                       wxDefaultPosition, wxDefaultSize);
+  pyrCtrl->SetValue(false);
+  optSizer->Add(pyrCtrl, 0, wxALIGN_LEFT | wxALL, 5);
+  wxTextCtrl *doneCtrl = new wxTextCtrl(this, ID_LOAD_LIST_DONE, ListDone,
+                                        wxDefaultPosition, wxSize(650, 100),
+                                        wxTE_MULTILINE | wxTE_READONLY |
+                                        wxTE_RICH2);
+  optBoxSizer->Add(doneCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+
+// OK - CANCEL buttons
+  wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Import"));
+  okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Quit"));
+  okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *abort = new wxButton(this, ID_LOAD_ABORT, wxT("&Abort"));
+  abort->Enable(false);
+  okCancelBox->Add(abort, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & ImportRasterDialog::OnOk);
+  Connect(ID_LOAD_ABORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & ImportRasterDialog::OnCmdAbort);
+  Connect(ID_LOAD_FORCE_SRID, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) & ImportRasterDialog::OnCmdForceSridChanged);
+  Connect(ID_LOAD_RASTER_START, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & ImportRasterDialog::OnRequestStart);
+  Connect(ID_LOAD_RASTER_STOP, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & ImportRasterDialog::OnRequestStop);
+  Connect(ID_LOAD_RASTER_THREAD_FINISHED, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & ImportRasterDialog::OnThreadFinished);
+}
+
+void ImportRasterDialog::OnCmdForceSridChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Force SRID selection changed 
+//
+  wxCheckBox *forceSridCtrl = (wxCheckBox *) FindWindow(ID_LOAD_FORCE_SRID);
+  wxSpinCtrl *sridCtrl = (wxSpinCtrl *) FindWindow(ID_LOAD_SRID);
+  if (forceSridCtrl->IsChecked() == true)
+    {
+      sridCtrl->SetValue(Srid);
+      sridCtrl->Enable(true);
+  } else
+    sridCtrl->Enable(false);
+}
+
+void ImportRasterDialog::OnCmdAbort(wxCommandEvent & WXUNUSED(event))
+{
+//
+// aborting the Raster Import process
+//
+  if (Params.IsAbortPending() == true)
+    return;
+  Params.RequestAbort();
+  wxString report =
+    wxT("\nan ABORT request is now pending and will be accepted ASAP");
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_LIST_DONE);
+  wxColour fore = wxColour(255, 255, 255);
+  wxColour back = wxColour(192, 0, 0);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(report);
+}
+
+void ImportRasterDialog::OnRequestStart(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_LIST_DONE);
+  wxColour fore = wxColour(255, 255, 255);
+  wxColour back = wxColour(0, 0, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(msg);
+  doneCtrl->MarkDirty();
+}
+
+void ImportRasterDialog::OnRequestStop(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_LIST_DONE);
+  ListDone += msg;
+  doneCtrl->Clear();
+  wxColour fore = wxColour(0, 0, 0);
+  wxColour back = wxColour(255, 255, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(ListDone);
+  doneCtrl->MarkDirty();
+}
+
+#ifdef _WIN32
+DWORD WINAPI DoExecuteRasterLoad(void *arg)
+#else
+void *DoExecuteRasterLoad(void *arg)
+#endif
+{
+//
+// threaded function: processing a Raster Import operation
+//
+  RasterLoadParams *params = (RasterLoadParams *) arg;
+  const char *sql;
+  int ret;
+  sqlite3_stmt *stmt = NULL;
+  int count = params->GetPathsCount();
+  int i;
+  clock_t clock_start;
+  clock_t clock_end;
+  double seconds;
+  char elapsed[64];
+  char ordinal[64];
+  wxString report;
+  wxString path;
+  wxCommandEvent evt_start(wxEVT_COMMAND_BUTTON_CLICKED, ID_LOAD_RASTER_START);
+  wxCommandEvent evt_stop(wxEVT_COMMAND_BUTTON_CLICKED, ID_LOAD_RASTER_STOP);
+
+  sql = "SELECT RL2_LoadRaster(?, ?, ?, ?, ?, 1)";
+  ret =
+    sqlite3_prepare_v2(params->GetMainFrame()->GetSqlite(), sql, strlen(sql),
+                       &stmt, NULL);
+  if (ret != SQLITE_OK)
+    {
+      params->SetError();
+      goto error;
+    }
+
+  for (i = 0; i < count; i++)
+    {
+      // loading each Raster File
+      if (params->IsAbortPending() == true)
+        {
+          report = wxT("STOP .... aborted by the user !!!!");
+          evt_start.SetString(report);
+          params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_start);
+          break;
+        }
+      path = params->GetPathByIndex(i);
+      params->SetCurrentPath(path);
+      report = wxT("Loading: ") + path;
+      evt_start.SetString(report);
+      params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_start);
+      clock_start = clock();
+      if (params->GetMainFrame()->DoImportRaster
+          (stmt, params->GetCoverageName(), path, params->GetSrid(),
+           params->IsWithWorldFile(), params->IsPyramidize()) != true)
+        {
+          params->SetError();
+          goto error;
+        }
+      clock_end = clock();
+      seconds = (double) (clock_end - clock_start) / (double) CLOCKS_PER_SEC;
+      MyResultSetView::FormatElapsedTime(seconds, elapsed);
+      sprintf(ordinal, "done %d/%d: ", i + 1, count);
+      report =
+        wxString::FromUTF8(ordinal) + path + wxT("    [") +
+        wxString::FromUTF8(elapsed) + wxT("]\n");
+      evt_stop.SetString(report);
+      params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_stop);
+      params->Done();
+    }
+  sqlite3_finalize(stmt);
+  goto end;
+
+error:
+  sqlite3_finalize(stmt);
+  report = wxT("FAILED: ") + path;
+  evt_stop.SetString(report);
+  params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_stop);
+  params->SetError();
+end:
+  wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED,
+                       ID_LOAD_RASTER_THREAD_FINISHED);
+  params->GetDlg()->GetEventHandler()->AddPendingEvent(event);
+#ifdef _WIN32
+  return 0;
+#else
+  pthread_exit(NULL);
+#endif
+}
+
+void ImportRasterDialog::OnThreadFinished(wxCommandEvent & WXUNUSED(event))
+{
+// resuming execution when the Import Raster thread quits
+  ::wxEndBusyCursor();
+  wxButton *quitBtn = (wxButton *) FindWindow(wxID_CANCEL);
+  wxButton *abortBtn = (wxButton *) FindWindow(ID_LOAD_ABORT);
+  quitBtn->Enable(true);
+  abortBtn->Enable(false);
+  if (Params.GetError() == true)
+    {
+      char dummy[80];
+      sprintf(dummy, "%d Raster files have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy) +
+                   wxT("\n\nA fatal error occurred while loading:\n") +
+                   Params.GetCurrentPath(), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+  } else if (Params.IsAbortPending() == true)
+    {
+      char dummy[80];
+      sprintf(dummy, "%d Raster files have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy) +
+                   wxT("\n\nStopped by an Abort user request"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+  } else
+    {
+      char dummy[80];
+      sprintf(dummy, "%d Raster files have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy), wxT("spatialite_gui"),
+                   wxOK | wxICON_INFORMATION, this);
+    }
+}
+
+void ImportRasterDialog::DoRunLoad()
+{
+//
+// executing the Load Raster(s) process in a separate Thread
+//
+#ifdef _WIN32
+  HANDLE thread_handle;
+  DWORD dwThreadId;
+#else
+  pthread_t thread_id;
+#endif
+  Params.Initialize(MainFrame, this, CoverageName, Paths, Srid, WithWorldFile,
+                    Pyramidize);
+#ifdef _WIN32
+  thread_handle =
+    CreateThread(NULL, 0, DoExecuteRasterLoad, &Params, 0, &dwThreadId);
+  SetThreadPriority(thread_handle, THREAD_PRIORITY_IDLE);
+#else
+  int ok_prior = 0;
+  int policy;
+  int min_prio;
+  pthread_attr_t attr;
+  struct sched_param sp;
+  pthread_attr_init(&attr);
+  if (pthread_attr_setschedpolicy(&attr, SCHED_RR) == 0)
+    {
+      // attempting to set the lowest priority  
+      if (pthread_attr_getschedpolicy(&attr, &policy) == 0)
+        {
+          min_prio = sched_get_priority_min(policy);
+          sp.sched_priority = min_prio;
+          if (pthread_attr_setschedparam(&attr, &sp) == 0)
+            {
+              // ok, setting the lowest priority  
+              ok_prior = 1;
+              pthread_create(&thread_id, &attr, DoExecuteRasterLoad, &Params);
+            }
+        }
+    }
+  if (!ok_prior)
+    {
+      // failure: using standard priority
+      pthread_create(&thread_id, NULL, DoExecuteRasterLoad, &Params);
+    }
+#endif
+}
+
+void ImportRasterDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxCheckBox *forceSridCtrl = (wxCheckBox *) FindWindow(ID_LOAD_FORCE_SRID);
+  wxSpinCtrl *sridCtrl = (wxSpinCtrl *) FindWindow(ID_LOAD_SRID);
+  wxCheckBox *worldCtrl = (wxCheckBox *) FindWindow(ID_LOAD_WITH_WORLDFILE);
+  wxCheckBox *pyramidCtrl = (wxCheckBox *) FindWindow(ID_LOAD_PYRAMIDIZE);
+  wxButton *loadBtn = (wxButton *) FindWindow(wxID_OK);
+  wxButton *quitBtn = (wxButton *) FindWindow(wxID_CANCEL);
+  wxButton *abortBtn = (wxButton *) FindWindow(ID_LOAD_ABORT);
+  if (forceSridCtrl->IsChecked() == true)
+    {
+      ForceSrid = true;
+      Srid = sridCtrl->GetValue();
+  } else
+    {
+      ForceSrid = false;
+      Srid = -1;
+    }
+  if (worldCtrl->IsChecked() == true)
+    WithWorldFile = true;
+  else
+    WithWorldFile = false;
+  if (pyramidCtrl->IsChecked() == true)
+    Pyramidize = true;
+  else
+    Pyramidize = false;
+  forceSridCtrl->Enable(false);
+  sridCtrl->Enable(false);
+  worldCtrl->Enable(false);
+  pyramidCtrl->Enable(false);
+  loadBtn->Enable(false);
+  quitBtn->Enable(false);
+  abortBtn->Enable(true);
+  ::wxBeginBusyCursor();
+  DoRunLoad();
+}
+
+bool PyramidizeDialog::Create(MyFrame * parent, wxString & coverage,
+                              wxString & title, wxString & abstract,
+                              wxString & sample, wxString & pixel,
+                              wxString & compression)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  CoverageName = coverage;
+  Title = title;
+  Abstract = abstract;
+  Sample = sample;
+  Pixel = pixel;
+  Compression = compression;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT
+                       ("Building MultiResolution Pyramid Levels (by Section)"))
+      == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void PyramidizeDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Coverage Name
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *cvgLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("Coverage &Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, wxID_ANY, CoverageName,
+                                       wxDefaultPosition, wxSize(600, 22),
+                                       wxTE_READONLY);
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the Coverage Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, wxID_ANY, Title,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the Coverage Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl = new wxTextCtrl(this, wxID_ANY, Abstract,
+                                            wxDefaultPosition, wxSize(600, 60),
+                                            wxTE_MULTILINE | wxTE_READONLY);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the Sample Type
+  wxBoxSizer *sampleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(sampleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *sampleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Sample Type:"));
+  sampleSizer->Add(sampleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *sampleCtrl = new wxTextCtrl(this, wxID_ANY, Sample,
+                                          wxDefaultPosition, wxSize(600, 22),
+                                          wxTE_READONLY);
+  sampleSizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fifth row: the Pixel Type
+  wxBoxSizer *pixelSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(pixelSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *pixelLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Pixel Type:"));
+  pixelSizer->Add(pixelLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *pixelCtrl = new wxTextCtrl(this, wxID_ANY, Pixel,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  pixelSizer->Add(pixelCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// sixth row: the Compression Type
+  wxBoxSizer *comprSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(comprSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *comprLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Compression:"));
+  comprSizer->Add(comprLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *comprCtrl = new wxTextCtrl(this, wxID_ANY, Compression,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  comprSizer->Add(comprCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// seventh row, mode force all
+  wxString mode[2];
+  mode[0] = wxT("&Only build missing Section Pyramids");
+  mode[1] = wxT("&Unconditionally re-build all Section Pyramids");
+  wxRadioBox *modeBox = new wxRadioBox(this, ID_PYRAMID_MODE,
+                                       wxT("&Mode selection"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 2,
+                                       mode, 1,
+                                       wxRA_SPECIFY_COLS);
+  boxSizer->Add(modeBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  modeBox->SetSelection(0);
+
+// OK - CANCEL buttons
+  wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Pyramidize"));
+  okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Quit"));
+  okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & PyramidizeDialog::OnOk);
+}
+
+bool PyramidizeDialog::DoPyramidize()
+{
+//
+// Building Section Pyramid levels */
+//
+  int ret;
+  bool force = false;
+  wxRadioBox *mode = (wxRadioBox *) FindWindow(ID_PYRAMID_MODE);
+  if (mode->GetSelection() == 1)
+    force = true;
+  ::wxBeginBusyCursor();
+  ret =
+    rl2_build_all_section_pyramids(MainFrame->GetSqlite(),
+                                   MainFrame->GetRL2MaxThreads(),
+                                   CoverageName.ToUTF8(), force, 1);
+  ::wxEndBusyCursor();
+  if (ret == RL2_OK)
+    return true;
+  else
+    return false;
+}
+
+void PyramidizeDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  if (DoPyramidize() == true)
+    wxMessageBox(wxT
+                 ("Section Pyramids successfully built on Raster Coverage \"") +
+                 CoverageName + wxT("\""), wxT("spatialite_gui"),
+                 wxOK | wxICON_INFORMATION, this);
+  else
+    wxMessageBox(wxT("Failure: some unexpected error occurred"),
+                 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+  wxDialog::EndModal(wxID_CANCEL);
+}
+
+bool PyramidizeMonolithicDialog::Create(MyFrame * parent, wxString & coverage,
+                                        wxString & title, wxString & abstract,
+                                        wxString & sample, wxString & pixel,
+                                        wxString & compression)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  CoverageName = coverage;
+  Title = title;
+  Abstract = abstract;
+  Sample = sample;
+  Pixel = pixel;
+  Compression = compression;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT
+                       ("Building MultiResolution Pyramid Levels (Monolithic)"))
+      == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void PyramidizeMonolithicDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Coverage Name
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *cvgLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("Coverage &Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, wxID_ANY, CoverageName,
+                                       wxDefaultPosition, wxSize(600, 22),
+                                       wxTE_READONLY);
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the Coverage Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, wxID_ANY, Title,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the Coverage Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl = new wxTextCtrl(this, wxID_ANY, Abstract,
+                                            wxDefaultPosition, wxSize(600, 60),
+                                            wxTE_MULTILINE | wxTE_READONLY);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the Sample Type
+  wxBoxSizer *sampleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(sampleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *sampleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Sample Type:"));
+  sampleSizer->Add(sampleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *sampleCtrl = new wxTextCtrl(this, wxID_ANY, Sample,
+                                          wxDefaultPosition, wxSize(600, 22),
+                                          wxTE_READONLY);
+  sampleSizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fifth row: the Pixel Type
+  wxBoxSizer *pixelSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(pixelSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *pixelLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Pixel Type:"));
+  pixelSizer->Add(pixelLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *pixelCtrl = new wxTextCtrl(this, wxID_ANY, Pixel,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  pixelSizer->Add(pixelCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// sixth row: the Compression Type
+  wxBoxSizer *comprSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(comprSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *comprLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Compression:"));
+  comprSizer->Add(comprLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *comprCtrl = new wxTextCtrl(this, wxID_ANY, Compression,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  comprSizer->Add(comprCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// seventh row, mode force all
+  wxString mode[3];
+  mode[0] =
+    wxT("All Pyramid Levels are &Physical, there are no Virtual Levels");
+  mode[1] = wxT("Interleave-1: every Physical Level supports a &Virtual Level");
+  mode[2] =
+    wxT("Interleave-2: every Physical Level supports &two Virtual Levels");
+  wxRadioBox *modeBox = new wxRadioBox(this, ID_PYRAMID_MODE,
+                                       wxT("&Mode selection"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 3,
+                                       mode, 1,
+                                       wxRA_SPECIFY_COLS);
+  boxSizer->Add(modeBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  if (Sample == wxT("1-BIT") || Sample == wxT("2-BIT")
+      || Sample == wxT("4-BIT"))
+    modeBox->SetSelection(0);
+  else
+    modeBox->SetSelection(2);
+
+// OK - CANCEL buttons
+  wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Pyramidize"));
+  okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Quit"));
+  okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & PyramidizeMonolithicDialog::OnOk);
+}
+
+bool PyramidizeMonolithicDialog::DoPyramidizeMonolithic()
+{
+//
+// Building Monolithic Pyramid levels */
+//
+  int ret;
+  int num_levels = 0;
+  wxRadioBox *mode = (wxRadioBox *) FindWindow(ID_PYRAMID_MODE);
+  if (mode->GetSelection() == 0)
+    num_levels = 1;
+  if (mode->GetSelection() == 1)
+    num_levels = 2;
+  if (mode->GetSelection() == 2)
+    num_levels = 3;
+  ::wxBeginBusyCursor();
+  ret =
+    rl2_build_monolithic_pyramid(MainFrame->GetSqlite(), CoverageName.ToUTF8(),
+                                 num_levels, 1);
+  ::wxEndBusyCursor();
+  if (ret == RL2_OK)
+    return true;
+  else
+    return false;
+}
+
+void PyramidizeMonolithicDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+//
+  if (DoPyramidizeMonolithic() == true)
+    wxMessageBox(wxT
+                 ("Monolithic Pyramid successfully built on Raster Coverage \"")
+                 + CoverageName + wxT("\""), wxT("spatialite_gui"),
+                 wxOK | wxICON_INFORMATION, this);
+  else
+    wxMessageBox(wxT("Failure: some unexpected error occurred"),
+                 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+  wxDialog::EndModal(wxID_CANCEL);
+}
+
+bool DePyramidizeDialog::Create(MyFrame * parent, wxString & coverage,
+                                wxString & title, wxString & abstract,
+                                wxString & sample, wxString & pixel,
+                                wxString & compression)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  CoverageName = coverage;
+  Title = title;
+  Abstract = abstract;
+  Sample = sample;
+  Pixel = pixel;
+  Compression = compression;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Removing MultiResolution Pyramid Levels")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void DePyramidizeDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Coverage Name
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *cvgLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("Coverage &Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, wxID_ANY, CoverageName,
+                                       wxDefaultPosition, wxSize(600, 22),
+                                       wxTE_READONLY);
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the Coverage Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, wxID_ANY, Title,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the Coverage Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl = new wxTextCtrl(this, wxID_ANY, Abstract,
+                                            wxDefaultPosition, wxSize(600, 60),
+                                            wxTE_MULTILINE | wxTE_READONLY);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the Sample Type
+  wxBoxSizer *sampleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(sampleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *sampleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Sample Type:"));
+  sampleSizer->Add(sampleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *sampleCtrl = new wxTextCtrl(this, wxID_ANY, Sample,
+                                          wxDefaultPosition, wxSize(600, 22),
+                                          wxTE_READONLY);
+  sampleSizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fifth row: the Pixel Type
+  wxBoxSizer *pixelSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(pixelSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *pixelLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Pixel Type:"));
+  pixelSizer->Add(pixelLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *pixelCtrl = new wxTextCtrl(this, wxID_ANY, Pixel,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  pixelSizer->Add(pixelCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// sixth row: the Compression Type
+  wxBoxSizer *comprSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(comprSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *comprLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Compression:"));
+  comprSizer->Add(comprLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *comprCtrl = new wxTextCtrl(this, wxID_ANY, Compression,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  comprSizer->Add(comprCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// seventh row: confirm message
+  wxBoxSizer *msgSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(msgSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 10);
+  wxString confirm =
+    wxT
+    ("All multi-resolution Pyramid Levels supporting this Raster Coverage will be irreversibly destroyed");
+  wxStaticText *msg1Label = new wxStaticText(this, wxID_STATIC, confirm);
+  msgSizer->Add(msg1Label, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  confirm = wxT("Do you really confirm De-Pyramidizing the Raster Coverage ?");
+  wxStaticText *msg2Label = new wxStaticText(this, wxID_STATIC, confirm);
+  msgSizer->Add(msg2Label, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+
+// OK - CANCEL buttons
+  wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&DePyramidize"));
+  okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Quit"));
+  okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & DePyramidizeDialog::OnOk);
+}
+
+bool DePyramidizeDialog::DoDePyramidize()
+{
+//
+// Deleting all Pyramid levels */
+//
+  int ret;
+  ::wxBeginBusyCursor();
+  ret = rl2_delete_all_pyramids(MainFrame->GetSqlite(), CoverageName.ToUTF8());
+  ::wxEndBusyCursor();
+  if (ret == RL2_OK)
+    return true;
+  else
+    return false;
+}
+
+void DePyramidizeDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  if (DoDePyramidize() == true)
+    wxMessageBox(wxT
+                 ("Pyramid Levels successfully removed from Raster Coverage \"")
+                 + CoverageName + wxT("\""), wxT("spatialite_gui"),
+                 wxOK | wxICON_INFORMATION, this);
+  else
+    wxMessageBox(wxT("Failure: some unexpected error occurred"),
+                 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+  wxDialog::EndModal(wxID_CANCEL);
+}
+
+bool RasterDropDialog::Create(MyFrame * parent, wxString & coverage,
+                              wxString & title, wxString & abstract,
+                              wxString & sample, wxString & pixel,
+                              wxString & compression)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  CoverageName = coverage;
+  Title = title;
+  Abstract = abstract;
+  Sample = sample;
+  Pixel = pixel;
+  Compression = compression;
+  if (wxDialog::Create(parent, wxID_ANY, wxT("Drop Raster Coverage")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void RasterDropDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Coverage Name
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *cvgLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("Coverage &Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, wxID_ANY, CoverageName,
+                                       wxDefaultPosition, wxSize(600, 22),
+                                       wxTE_READONLY);
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the Coverage Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, wxID_ANY, Title,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the Coverage Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl = new wxTextCtrl(this, wxID_ANY, Abstract,
+                                            wxDefaultPosition, wxSize(600, 60),
+                                            wxTE_MULTILINE | wxTE_READONLY);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the Sample Type
+  wxBoxSizer *sampleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(sampleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *sampleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Sample Type:"));
+  sampleSizer->Add(sampleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *sampleCtrl = new wxTextCtrl(this, wxID_ANY, Sample,
+                                          wxDefaultPosition, wxSize(600, 22),
+                                          wxTE_READONLY);
+  sampleSizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fifth row: the Pixel Type
+  wxBoxSizer *pixelSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(pixelSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *pixelLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Pixel Type:"));
+  pixelSizer->Add(pixelLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *pixelCtrl = new wxTextCtrl(this, wxID_ANY, Pixel,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  pixelSizer->Add(pixelCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// sixth row: the Compression Type
+  wxBoxSizer *comprSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(comprSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *comprLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Compression:"));
+  comprSizer->Add(comprLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *comprCtrl = new wxTextCtrl(this, wxID_ANY, Compression,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  comprSizer->Add(comprCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// seventh row: confirm message
+  wxBoxSizer *msgSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(msgSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 10);
+  wxString confirm =
+    wxT
+    ("This Raster Coverage will be completely and irreversibly removed from the DBMS");
+  wxStaticText *msg1Label = new wxStaticText(this, wxID_STATIC, confirm);
+  msgSizer->Add(msg1Label, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  confirm = wxT("Do you really confirm dropping the Raster Coverage ?");
+  wxStaticText *msg2Label = new wxStaticText(this, wxID_STATIC, confirm);
+  msgSizer->Add(msg2Label, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+
+// OK - CANCEL buttons
+  wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Drop"));
+  okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Quit"));
+  okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterDropDialog::OnOk);
+}
+
+bool RasterDropDialog::DoDropCoverage()
+{
+//
+// Dropping a Raster Coverage
+//
+  rl2CoveragePtr cvg = NULL;
+  ::wxBeginBusyCursor();
+  cvg =
+    rl2_create_coverage_from_dbms(MainFrame->GetSqlite(),
+                                  CoverageName.ToUTF8());
+  if (cvg == NULL)
+    goto error;
+  if (rl2_drop_dbms_coverage(MainFrame->GetSqlite(), CoverageName.ToUTF8()) !=
+      RL2_OK)
+    goto error;
+  rl2_destroy_coverage(cvg);
+  ::wxEndBusyCursor();
+  return true;
+
+error:
+  if (cvg != NULL)
+    rl2_destroy_coverage(cvg);
+  ::wxEndBusyCursor();
+  return false;
+}
+
+void RasterDropDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  if (DoDropCoverage() == true)
+    wxMessageBox(wxT("Raster Coverage \"") + CoverageName +
+                 wxT("\" successfully removed from the DBMS\n\n") +
+                 wxT
+                 ("You could now eventually consider to execute VACUUM in order to reclaim the unused disk space."),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  else
+    wxMessageBox(wxT("Failure: some unexpected error occurred"),
+                 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+  wxDialog::EndModal(wxID_CANCEL);
+}
+
+bool VectorUnregisterDialog::Create(MyFrame * parent, wxString & coverage,
+                                    wxString & title, wxString & abstract,
+                                    wxString & type)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  CoverageName = coverage;
+  Title = title;
+  Abstract = abstract;
+  Type = type;
+  if (wxDialog::Create(parent, wxID_ANY, wxT("Unregister Vector Coverage")) ==
+      false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void VectorUnregisterDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Coverage Name
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *cvgLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("Coverage &Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, wxID_ANY, CoverageName,
+                                       wxDefaultPosition, wxSize(600, 22),
+                                       wxTE_READONLY);
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the Coverage Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, wxID_ANY, Title,
+                                         wxDefaultPosition, wxSize(600, 22),
+                                         wxTE_READONLY);
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the Coverage Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl = new wxTextCtrl(this, wxID_ANY, Abstract,
+                                            wxDefaultPosition, wxSize(600, 60),
+                                            wxTE_MULTILINE | wxTE_READONLY);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the Geometry Type
+  wxBoxSizer *sampleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(sampleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *sampleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Geometry Type:"));
+  sampleSizer->Add(sampleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *sampleCtrl = new wxTextCtrl(this, wxID_ANY, Type,
+                                          wxDefaultPosition, wxSize(600, 22),
+                                          wxTE_READONLY);
+  sampleSizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// seventh row: confirm message
+  wxBoxSizer *msgSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(msgSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 10);
+  wxString confirm =
+    wxT
+    ("This Vector Coverage will be UnRegistered preserving the underlying Spatial Table");
+  wxStaticText *msg1Label = new wxStaticText(this, wxID_STATIC, confirm);
+  msgSizer->Add(msg1Label, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  confirm = wxT("Do you really confirm unregistering the Vector Coverage ?");
+  wxStaticText *msg2Label = new wxStaticText(this, wxID_STATIC, confirm);
+  msgSizer->Add(msg2Label, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+
+// OK - CANCEL buttons
+  wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&UnRegister"));
+  okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Quit"));
+  okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & VectorUnregisterDialog::OnOk);
+}
+
+bool VectorUnregisterDialog::DoVectorUnregister()
+{
+//
+// UnRegistering a Vector Coverage
+//
+  sqlite3_stmt *stmt = NULL;
+  int valid = 0;
+  ::wxBeginBusyCursor();
+  const char *sql = "SELECT SE_UnRegisterVectorStyle(?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    goto error;
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1, SQLITE_STATIC);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        goto error;
+    }
+  sqlite3_finalize(stmt);
+  stmt = NULL;
+  if (!valid)
+    goto error;
+  ::wxEndBusyCursor();
+  return true;
+
+error:
+  ::wxEndBusyCursor();
+  return false;
+}
+
+void VectorUnregisterDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  if (DoVectorUnregister() == true)
+    wxMessageBox(wxT("Vector Coverage \"") + CoverageName +
+                 wxT("\" successfully UnRegistered."),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  else
+    wxMessageBox(wxT("Failure: some unexpected error occurred"),
+                 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+  wxDialog::EndModal(wxID_CANCEL);
+}
diff --git a/RasterSymbolizers.cpp b/RasterSymbolizers.cpp
new file mode 100644
index 0000000..c6da600
--- /dev/null
+++ b/RasterSymbolizers.cpp
@@ -0,0 +1,6005 @@
+/*
+/ RasterSymbolizers.cpp
+/ various dialog classes
+/
+/ version 1.8, 2015 March 23
+/
+/ Author: Sandro Furieri a-furieri at lqt.it
+/
+/ Copyright (C) 2015  Alessandro Furieri
+/
+/    This program is free software: you can redistribute it and/or modify
+/    it under the terms of the GNU General Public License as published by
+/    the Free Software Foundation, either version 3 of the License, or
+/    (at your option) any later version.
+/
+/    This program is distributed in the hope that it will be useful,
+/    but WITHOUT ANY WARRANTY; without even the implied warranty of
+/    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/    GNU General Public License for more details.
+/
+/    You should have received a copy of the GNU General Public License
+/    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+/
+*/
+
+#include "Classdef.h"
+
+#include "wx/spinctrl.h"
+#include "wx/filename.h"
+#include "wx/colordlg.h"
+#include "wx/clipbrd.h"
+
+bool RasterSymbolizerContrastDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Normalize = true;
+  Histogram = false;
+  Gamma = false;
+  MinScale = false;
+  MaxScale = false;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("RasterSymbolizer: ContrastEnhancement")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void RasterSymbolizerContrastDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the RasterSymbolizer Name
+  wxBoxSizer *nameSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(nameSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *nameLabel = new wxStaticText(this, wxID_STATIC, wxT("&Name:"));
+  nameSizer->Add(nameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *nameCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_NAME, wxT(""),
+                                        wxDefaultPosition, wxSize(600, 22));
+  nameSizer->Add(nameCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the RasterSymbolizer Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the RasterSymbolizer Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_ABSTRACT, wxT(""),
+                   wxDefaultPosition, wxSize(600, 60),
+                   wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the RasterSymbolizer Opacity
+  wxBoxSizer *opacitySizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacitySizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *opacityLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Opacity:"));
+  opacitySizer->Add(opacityLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSlider *opacityCtrl = new wxSlider(this, ID_SYMBOLIZER_OPACITY, 100, 0, 100,
+                                       wxDefaultPosition, wxSize(600, 45),
+                                       wxSL_HORIZONTAL | wxSL_LABELS);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// fifth row: Contrast Enhancement
+  wxBoxSizer *contrastSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(contrastSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxString contrast[3];
+  contrast[0] = wxT("&Normalize/Stretch");
+  contrast[1] = wxT("&Histogram");
+  contrast[2] = wxT("&GammaValue");
+  wxRadioBox *contrastBox = new wxRadioBox(this, ID_SYMBOLIZER_CONTRAST,
+                                           wxT("&Contrast Enhancement Method"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize, 3,
+                                           contrast, 1,
+                                           wxRA_SPECIFY_ROWS);
+  contrastSizer->Add(contrastBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  contrastBox->SetSelection(0);
+  wxBoxSizer *gammaSizer = new wxBoxSizer(wxHORIZONTAL);
+  contrastSizer->Add(gammaSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticText *gammaLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&GammaValue [x100]:"));
+  gammaSizer->Add(gammaLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSpinCtrl *gammaCtrl = new wxSpinCtrl(this, ID_SYMBOLIZER_GAMMA, wxT("100"),
+                                         wxDefaultPosition, wxSize(80, 22),
+                                         wxSP_ARROW_KEYS,
+                                         100, 500, 100);
+  gammaCtrl->Enable(false);
+  gammaSizer->Add(gammaCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// sixth row: optional Visibility Range
+  wxBoxSizer *visibilityBoxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(visibilityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *visibilityBox = new wxStaticBox(this, wxID_STATIC,
+                                               wxT("Visibility Range"),
+                                               wxDefaultPosition,
+                                               wxDefaultSize);
+  wxBoxSizer *visibilitySizer =
+    new wxStaticBoxSizer(visibilityBox, wxHORIZONTAL);
+  visibilityBoxSizer->Add(visibilitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL,
+                          5);
+  wxString range[4];
+  range[0] = wxT("&None");
+  range[1] = wxT("&Min");
+  range[2] = wxT("&Max");
+  range[3] = wxT("&Both");
+  wxRadioBox *rangeBox = new wxRadioBox(this, ID_SYMBOLIZER_MINMAX_SCALE,
+                                        wxT("&Range Type"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 4,
+                                        range, 2,
+                                        wxRA_SPECIFY_COLS);
+  visibilitySizer->Add(rangeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  rangeBox->SetSelection(0);
+  visibilitySizer->AddSpacer(20);
+  wxBoxSizer *scaleBoxSizer = new wxBoxSizer(wxVERTICAL);
+  visibilitySizer->Add(scaleBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *scaleMinSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMinSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *minScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Min Scale:"));
+  scaleMinSizer->Add(minScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *minScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MIN_SCALE, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  minScaleCtrl->Enable(false);
+  scaleMinSizer->Add(minScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *scaleMaxSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMaxSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *maxScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Max Scale:"));
+  scaleMaxSizer->Add(maxScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *maxScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MAX_SCALE, wxT("+Infinite"),
+                   wxDefaultPosition, wxSize(100, 22));
+  maxScaleCtrl->Enable(false);
+  scaleMaxSizer->Add(maxScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *insert =
+    new wxButton(this, ID_SYMBOLIZER_INSERT, wxT("&Insert into DBMS"));
+  btnBox->Add(insert, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *exp =
+    new wxButton(this, ID_SYMBOLIZER_EXPORT, wxT("&Export to file"));
+  btnBox->Add(exp, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *copy = new wxButton(this, ID_SYMBOLIZER_COPY, wxT("&Copy"));
+  btnBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerContrastDialog::OnQuit);
+  Connect(ID_SYMBOLIZER_INSERT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerContrastDialog::OnInsert);
+  Connect(ID_SYMBOLIZER_EXPORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerContrastDialog::OnExport);
+  Connect(ID_SYMBOLIZER_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerContrastDialog::OnCopy);
+  Connect(ID_SYMBOLIZER_CONTRAST, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerContrastDialog::OnCmdModeChanged);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerContrastDialog::OnCmdScaleChanged);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerContrastDialog::OnCmdScaleChanged);
+}
+
+void RasterSymbolizerContrastDialog::
+OnCmdModeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Contrast Enhancement Method selection changed
+//
+  wxRadioBox *contrastCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_CONTRAST);
+  wxSpinCtrl *gammaCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_GAMMA);
+  switch (contrastCtrl->GetSelection())
+    {
+      case 0:
+        Normalize = true;
+        Histogram = false;
+        Gamma = false;
+        gammaCtrl->Enable(false);
+        break;
+      case 1:
+        Normalize = false;
+        Histogram = true;
+        Gamma = false;
+        gammaCtrl->Enable(false);
+        break;
+      case 2:
+        Normalize = false;
+        Histogram = false;
+        Gamma = true;
+        gammaCtrl->Enable(true);
+        break;
+    };
+}
+
+void RasterSymbolizerContrastDialog::
+OnCmdScaleChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Visibility Range selection changed
+//
+  wxRadioBox *scaleModeCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  switch (scaleModeCtrl->GetSelection())
+    {
+      case 0:
+        MinScale = false;
+        MaxScale = false;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 1:
+        MinScale = true;
+        MaxScale = false;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 2:
+        MinScale = false;
+        MaxScale = true;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+      case 3:
+        MinScale = true;
+        MaxScale = true;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+    };
+}
+
+bool RasterSymbolizerContrastDialog::RetrieveParams()
+{
+//
+// retrieving the RasterSymbolizer params 
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  Name = nameCtrl->GetValue();
+  if (Name.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the RasterSymbolizer NAME !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  Title = titleCtrl->GetValue();
+  if (Title.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer TITLE is warmly suggested\n\n");
+      msg += wxT("Do you really confirm leaving an empty (undefined) Title ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  Abstract = absCtrl->GetValue();
+  if (Abstract.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer ABSTRACT is warmly suggested\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an empty (undefined) Abstract ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_OPACITY);
+  Opacity = opacityCtrl->GetValue() / 100.0;
+  if (Gamma == true)
+    {
+      wxSpinCtrl *gammaCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_GAMMA);
+      GammaValue = gammaCtrl->GetValue() / 100.0;
+  } else
+    GammaValue = 1.0;
+  if (MinScale == true)
+    {
+      wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+      wxString value = minCtrl->GetValue();
+      if (value.ToDouble(&MinScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MinScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MaxScale == true)
+    {
+      wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+      wxString value = maxCtrl->GetValue();
+      if (value.ToDouble(&MaxScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MaxScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MinScale == true && MaxScale == true)
+    {
+      if (MinScaleDenominator >= MaxScaleDenominator)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE is always expected to be greater than MIN_SCALE !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  return true;
+}
+
+char *RasterSymbolizerContrastDialog::DoCreateCoverageXML()
+{
+//
+// creating the SLD/SE (XML) code - CoverageStyle
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<CoverageStyle version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Rule>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (MinScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MinScaleDenominator>%1.2f</MinScaleDenominator>\r\n", prev,
+         MinScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MaxScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MaxScaleDenominator>%1.2f</MaxScaleDenominator>\r\n", prev,
+         MaxScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t<RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<ContrastEnhancement>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (Histogram == true)
+    {
+      xml = sqlite3_mprintf("%s\t\t\t\t<Histogram/>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+  } else if (Gamma == true)
+    {
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t<GammaValue>%1.2f</GammaValue>\r\n", prev,
+                        GammaValue);
+      sqlite3_free(prev);
+      prev = xml;
+  } else
+    {
+      xml = sqlite3_mprintf("%s\t\t\t\t<Normalize/>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t\t</ContrastEnhancement>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</Rule>\r\n</CoverageStyle>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+char *RasterSymbolizerContrastDialog::DoCreateSymbolizerXML()
+{
+//
+// creating the SLD/SE (XML) code - RasterSymbolizer
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<RasterSymbolizer version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/Symbolizer.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t<ContrastEnhancement>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (Histogram == true)
+    {
+      xml = sqlite3_mprintf("%s\t\t<Histogram/>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+  } else if (Gamma == true)
+    {
+      xml =
+        sqlite3_mprintf("%s\t\t<GammaValue>%1.2f</GammaValue>\r\n", prev,
+                        GammaValue);
+      sqlite3_free(prev);
+      prev = xml;
+  } else
+    {
+      xml = sqlite3_mprintf("%s\t\t<Normalize/>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t</ContrastEnhancement>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+void RasterSymbolizerContrastDialog::OnInsert(wxCommandEvent & WXUNUSED(event))
+{
+//
+// inserting the RasterSymbolizer into the DBMS
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  if (MainFrame->DoInsertRasterSymbolizer(xml) == true)
+    wxMessageBox(wxT
+                 ("SLD/SE RasterSymbolizer successfully registered into the DBMS"),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerContrastDialog::OnExport(wxCommandEvent & WXUNUSED(event))
+{
+//
+// exporting the RasterSymbolizer as an external file
+//
+  int ret;
+  wxString path;
+  wxString lastDir;
+  if (RetrieveParams() == false)
+    return;
+  wxFileDialog fileDialog(this,
+                          wxT("Exporting an SLD/SE RasterSymbolizer to a file"),
+                          wxT(""), Name + wxT(".xml"),
+                          wxT("XML Document|*.xml|All files (*.*)|*.*"),
+                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      wxFileName file(fileDialog.GetPath());
+      path = file.GetPath();
+      path += file.GetPathSeparator();
+      path += file.GetName();
+      lastDir = file.GetPath();
+      path = fileDialog.GetPath();
+      FILE *out = fopen(path.ToUTF8(), "wb");
+      if (out == NULL)
+        wxMessageBox(wxT("ERROR: unable to create:\n\n\"") + path + wxT("\""),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else
+        {
+          char *xml;
+          if (MinScale == true || MaxScale == true)
+            xml = DoCreateCoverageXML();
+          else
+            xml = DoCreateSymbolizerXML();
+          fwrite(xml, 1, strlen(xml), out);
+          sqlite3_free(xml);
+          fclose(out);
+          wxMessageBox(wxT
+                       ("SLD/SE RasterSymbolizer successfully saved into:\n\n\"")
+                       + path + wxT("\""), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerContrastDialog::OnCopy(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Copying the RasterSymbolizer into the Clipboard 
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  wxString XMLstring = wxString::FromUTF8(xml);
+  if (wxTheClipboard->Open())
+    {
+      wxTheClipboard->SetData(new wxTextDataObject(XMLstring));
+      wxTheClipboard->Close();
+    }
+}
+
+void RasterSymbolizerContrastDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool MyFrame::ValidateRasterStyle(void **blob, int *blob_size, const char *xml)
+{
+//
+// attempting to parse and validate a Raster Style
+//
+  int ret;
+  sqlite3_stmt *stmt;
+  void *xblob = NULL;
+  int xblob_size;
+  int valid = 0;
+
+// Schema validation
+  const char *sql = "SELECT XB_Create(?, 1, 1)";
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_blob(stmt, 1, xml, strlen(xml), SQLITE_STATIC);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_BLOB)
+            {
+              const void *xxblob = sqlite3_column_blob(stmt, 0);
+              xblob_size = sqlite3_column_bytes(stmt, 0);
+              xblob = malloc(xblob_size);
+              memcpy(xblob, xxblob, xblob_size);
+            }
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (xblob == NULL)
+    return false;
+
+// Checking if really is a Raster Style
+  stmt = NULL;
+  sql = "SELECT XB_IsSldSERasterStyle(?)";
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    goto invalid;
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_blob(stmt, 1, xblob, xblob_size, SQLITE_STATIC);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        goto invalid;
+    }
+  sqlite3_finalize(stmt);
+  stmt = NULL;
+  if (!valid)
+    goto invalid;
+  *blob = xblob;
+  *blob_size = xblob_size;
+  return true;
+
+invalid:
+  if (stmt != NULL)
+    sqlite3_finalize(stmt);
+  free(xblob);
+  *blob = NULL;
+  *blob_size = 0;
+  return false;
+}
+
+bool MyFrame::DoInsertRasterSymbolizer(char *xml)
+{
+//
+// attempting to register a RasterSymbolizer
+//
+  void *blob = NULL;
+  int blob_size;
+  ::wxBeginBusyCursor();
+  if (ValidateRasterStyle(&blob, &blob_size, xml) != true)
+    {
+      ::wxEndBusyCursor();
+      wxMessageBox(wxT("Error: not a valid SLD/SE RasterSymbolizer"),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(xml);
+      return false;
+    }
+  ::wxEndBusyCursor();
+  sqlite3_free(xml);
+
+  sqlite3_stmt *stmt = NULL;
+  const char *sql = "SELECT SE_RegisterRasterStyle(?)";
+  int ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_blob(stmt, 1, blob, blob_size, free);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+    ;
+  else
+    {
+      sqlite3_finalize(stmt);
+      return false;
+    }
+  sqlite3_finalize(stmt);
+  return true;
+}
+
+bool RasterSymbolizerChannelRgbDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Normalize = false;
+  Histogram = false;
+  Gamma = false;
+  MinScale = false;
+  MaxScale = false;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT
+                       ("RasterSymbolizer: ChannelSelection (RGB: false-colors)"))
+      == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void RasterSymbolizerChannelRgbDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the RasterSymbolizer Name
+  wxBoxSizer *nameSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(nameSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *nameLabel = new wxStaticText(this, wxID_STATIC, wxT("&Name:"));
+  nameSizer->Add(nameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *nameCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_NAME, wxT(""),
+                                        wxDefaultPosition, wxSize(600, 22));
+  nameSizer->Add(nameCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the RasterSymbolizer Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the RasterSymbolizer Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_ABSTRACT, wxT(""),
+                   wxDefaultPosition, wxSize(600, 60),
+                   wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the RasterSymbolizer Opacity
+  wxBoxSizer *opacitySizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacitySizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *opacityLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Opacity:"));
+  opacitySizer->Add(opacityLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSlider *opacityCtrl = new wxSlider(this, ID_SYMBOLIZER_OPACITY, 100, 0, 100,
+                                       wxDefaultPosition, wxSize(600, 45),
+                                       wxSL_HORIZONTAL | wxSL_LABELS);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// fifth row: ChannelSelection
+  wxBoxSizer *channelBoxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(channelBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *channelBox = new wxStaticBox(this, wxID_STATIC,
+                                            wxT
+                                            ("Channel Selection (first Band is #1)"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *channelSizer = new wxStaticBoxSizer(channelBox, wxVERTICAL);
+  channelBoxSizer->Add(channelSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *bandSizer = new wxBoxSizer(wxVERTICAL);
+  channelSizer->Add(bandSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *redSizer = new wxBoxSizer(wxHORIZONTAL);
+  bandSizer->Add(redSizer, 0, wxALIGN_RIGHT | wxALL, 3);
+  wxStaticText *redLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Red Channel is Band #"));
+  redSizer->Add(redLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSpinCtrl *redCtrl = new wxSpinCtrl(this, ID_SYMBOLIZER_RED, wxT("1"),
+                                       wxDefaultPosition, wxSize(80, 22),
+                                       wxSP_ARROW_KEYS,
+                                       1, 256, 1);
+  redSizer->Add(redCtrl, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxBoxSizer *greenSizer = new wxBoxSizer(wxHORIZONTAL);
+  bandSizer->Add(greenSizer, 0, wxALIGN_RIGHT | wxALL, 3);
+  wxStaticText *greenLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Green Channel is Band #"));
+  greenSizer->Add(greenLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSpinCtrl *greenCtrl = new wxSpinCtrl(this, ID_SYMBOLIZER_GREEN, wxT("2"),
+                                         wxDefaultPosition, wxSize(80, 22),
+                                         wxSP_ARROW_KEYS,
+                                         1, 256, 2);
+  greenSizer->Add(greenCtrl, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxBoxSizer *blueSizer = new wxBoxSizer(wxHORIZONTAL);
+  bandSizer->Add(blueSizer, 0, wxALIGN_RIGHT | wxALL, 3);
+  wxStaticText *blueLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Blue Channel is Band #"));
+  blueSizer->Add(blueLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSpinCtrl *blueCtrl = new wxSpinCtrl(this, ID_SYMBOLIZER_BLUE, wxT("3"),
+                                        wxDefaultPosition, wxSize(80, 22),
+                                        wxSP_ARROW_KEYS,
+                                        1, 256, 3);
+  blueSizer->Add(blueCtrl, 0, wxALIGN_RIGHT | wxALL, 0);
+// sixth row: Contrast Enhancement
+  wxBoxSizer *contrastSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(contrastSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxString contrast[4];
+  contrast[0] = wxT("&None");
+  contrast[1] = wxT("Normalize/&Stretch");
+  contrast[2] = wxT("&Histogram");
+  contrast[3] = wxT("&GammaValue");
+  wxRadioBox *contrastBox = new wxRadioBox(this, ID_SYMBOLIZER_CONTRAST,
+                                           wxT("&Contrast Enhancement Method"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize, 4,
+                                           contrast, 2,
+                                           wxRA_SPECIFY_COLS);
+  contrastSizer->Add(contrastBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  contrastBox->SetSelection(0);
+  wxBoxSizer *gammaSizer = new wxBoxSizer(wxHORIZONTAL);
+  contrastSizer->Add(gammaSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticText *gammaLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&GammaValue [x100]:"));
+  gammaSizer->Add(gammaLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSpinCtrl *gammaCtrl = new wxSpinCtrl(this, ID_SYMBOLIZER_GAMMA, wxT("100"),
+                                         wxDefaultPosition, wxSize(80, 22),
+                                         wxSP_ARROW_KEYS,
+                                         100, 500, 100);
+  gammaCtrl->Enable(false);
+  gammaSizer->Add(gammaCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// seventh row: optional Visibility Range
+  wxBoxSizer *visibilityBoxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(visibilityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *visibilityBox = new wxStaticBox(this, wxID_STATIC,
+                                               wxT("Visibility Range"),
+                                               wxDefaultPosition,
+                                               wxDefaultSize);
+  wxBoxSizer *visibilitySizer =
+    new wxStaticBoxSizer(visibilityBox, wxHORIZONTAL);
+  visibilityBoxSizer->Add(visibilitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL,
+                          5);
+  wxString range[4];
+  range[0] = wxT("&None");
+  range[1] = wxT("&Min");
+  range[2] = wxT("&Max");
+  range[3] = wxT("&Both");
+  wxRadioBox *rangeBox = new wxRadioBox(this, ID_SYMBOLIZER_MINMAX_SCALE,
+                                        wxT("&Range Type"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 4,
+                                        range, 2,
+                                        wxRA_SPECIFY_COLS);
+  visibilitySizer->Add(rangeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  rangeBox->SetSelection(0);
+  visibilitySizer->AddSpacer(20);
+  wxBoxSizer *scaleBoxSizer = new wxBoxSizer(wxVERTICAL);
+  visibilitySizer->Add(scaleBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *scaleMinSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMinSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *minScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Min Scale:"));
+  scaleMinSizer->Add(minScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *minScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MIN_SCALE, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  minScaleCtrl->Enable(false);
+  scaleMinSizer->Add(minScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *scaleMaxSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMaxSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *maxScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Max Scale:"));
+  scaleMaxSizer->Add(maxScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *maxScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MAX_SCALE, wxT("+Infinite"),
+                   wxDefaultPosition, wxSize(100, 22));
+  maxScaleCtrl->Enable(false);
+  scaleMaxSizer->Add(maxScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *insert =
+    new wxButton(this, ID_SYMBOLIZER_INSERT, wxT("&Insert into DBMS"));
+  btnBox->Add(insert, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *exp =
+    new wxButton(this, ID_SYMBOLIZER_EXPORT, wxT("&Export to file"));
+  btnBox->Add(exp, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *copy = new wxButton(this, ID_SYMBOLIZER_COPY, wxT("&Copy"));
+  btnBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerChannelRgbDialog::OnQuit);
+  Connect(ID_SYMBOLIZER_INSERT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerChannelRgbDialog::OnInsert);
+  Connect(ID_SYMBOLIZER_EXPORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerChannelRgbDialog::OnExport);
+  Connect(ID_SYMBOLIZER_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerChannelRgbDialog::OnCopy);
+  Connect(ID_SYMBOLIZER_CONTRAST, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerChannelRgbDialog::OnCmdModeChanged);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerChannelRgbDialog::OnCmdScaleChanged);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerChannelRgbDialog::OnCmdScaleChanged);
+}
+
+void RasterSymbolizerChannelRgbDialog::
+OnCmdModeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Contrast Enhancement Method selection changed
+//
+  wxRadioBox *contrastCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_CONTRAST);
+  wxSpinCtrl *gammaCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_GAMMA);
+  switch (contrastCtrl->GetSelection())
+    {
+      case 0:
+        Normalize = false;
+        Histogram = false;
+        Gamma = false;
+        gammaCtrl->Enable(false);
+        break;
+      case 1:
+        Normalize = true;
+        Histogram = false;
+        Gamma = false;
+        gammaCtrl->Enable(false);
+        break;
+      case 2:
+        Normalize = false;
+        Histogram = true;
+        Gamma = false;
+        gammaCtrl->Enable(false);
+        break;
+      case 3:
+        Normalize = false;
+        Histogram = false;
+        Gamma = true;
+        gammaCtrl->Enable(true);
+        break;
+    };
+}
+
+void RasterSymbolizerChannelRgbDialog::
+OnCmdScaleChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Visibility Range selection changed
+//
+  wxRadioBox *scaleModeCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  switch (scaleModeCtrl->GetSelection())
+    {
+      case 0:
+        MinScale = false;
+        MaxScale = false;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 1:
+        MinScale = true;
+        MaxScale = false;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 2:
+        MinScale = false;
+        MaxScale = true;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+      case 3:
+        MinScale = true;
+        MaxScale = true;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+    };
+}
+
+bool RasterSymbolizerChannelRgbDialog::RetrieveParams()
+{
+//
+// retrieving the RasterSymbolizer params 
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  Name = nameCtrl->GetValue();
+  if (Name.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the RasterSymbolizer NAME !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  Title = titleCtrl->GetValue();
+  if (Title.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer TITLE is warmly suggested\n\n");
+      msg += wxT("Do you really confirm leaving an empty (undefined) Title ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  Abstract = absCtrl->GetValue();
+  if (Abstract.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer ABSTRACT is warmly suggested\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an empty (undefined) Abstract ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_OPACITY);
+  Opacity = opacityCtrl->GetValue() / 100.0;
+  wxSpinCtrl *redCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_RED);
+  RedBand = redCtrl->GetValue();
+  wxSpinCtrl *greenCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_GREEN);
+  GreenBand = greenCtrl->GetValue();
+  wxSpinCtrl *blueCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_BLUE);
+  BlueBand = blueCtrl->GetValue();
+  if (Gamma == true)
+    {
+      wxSpinCtrl *gammaCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_GAMMA);
+      GammaValue = gammaCtrl->GetValue() / 100.0;
+  } else
+    GammaValue = 1.0;
+  if (MinScale == true)
+    {
+      wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+      wxString value = minCtrl->GetValue();
+      if (value.ToDouble(&MinScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MinScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MaxScale == true)
+    {
+      wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+      wxString value = maxCtrl->GetValue();
+      if (value.ToDouble(&MaxScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MaxScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MinScale == true && MaxScale == true)
+    {
+      if (MinScaleDenominator >= MaxScaleDenominator)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE is always expected to be greater than MIN_SCALE !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  return true;
+}
+
+char *RasterSymbolizerChannelRgbDialog::DoCreateCoverageXML()
+{
+//
+// creating the SLD/SE (XML) code - CoverageStyle
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<CoverageStyle version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Rule>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (MinScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MinScaleDenominator>%1.2f</MinScaleDenominator>\r\n", prev,
+         MinScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MaxScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MaxScaleDenominator>%1.2f</MaxScaleDenominator>\r\n", prev,
+         MaxScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t<RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<ChannelSelection>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t\t\t<RedChannel>\r\n\t\t\t\t\t<SourceChannelName>%d",
+                    prev, RedBand);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s</SourceChannelName>\r\n\t\t\t\t</RedChannel>\r\n",
+                    prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t\t\t<GreenChannel>\r\n\t\t\t\t\t<SourceChannelName>%d", prev,
+     GreenBand);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s</SourceChannelName>\r\n\t\t\t\t</GreenChannel>\r\n",
+                    prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t\t\t<BlueChannel>\r\n\t\t\t\t\t<SourceChannelName>%d", prev,
+     BlueBand);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s</SourceChannelName>\r\n\t\t\t\t</BlueChannel>\r\n",
+                    prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t</ChannelSelection>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (Normalize == true || Histogram == true || Gamma == true)
+    {
+      xml = sqlite3_mprintf("%s\t\t\t<ContrastEnhancement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Histogram == true)
+        {
+          xml = sqlite3_mprintf("%s\t\t\t\t<Histogram/>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+      } else if (Gamma == true)
+        {
+          xml =
+            sqlite3_mprintf("%s\t\t\t\t<GammaValue>%1.2f</GammaValue>\r\n",
+                            prev, GammaValue);
+          sqlite3_free(prev);
+          prev = xml;
+      } else
+        {
+          xml = sqlite3_mprintf("%s\t\t\t\t<Normalize/>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t\t</ContrastEnhancement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</Rule>\r\n</CoverageStyle>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+char *RasterSymbolizerChannelRgbDialog::DoCreateSymbolizerXML()
+{
+//
+// creating the SLD/SE (XML) code - RasterSymbolizer
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<RasterSymbolizer version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/Symbolizer.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t<ChannelSelection>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t<RedChannel>\r\n\t\t\t<SourceChannelName>%d", prev,
+                    RedBand);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s</SourceChannelName>\r\n\t\t</RedChannel>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t<GreenChannel>\r\n\t\t\t<SourceChannelName>%d", prev,
+                    GreenBand);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s</SourceChannelName>\r\n\t\t</GreenChannel>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t<BlueChannel>\r\n\t\t\t<SourceChannelName>%d", prev,
+                    BlueBand);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s</SourceChannelName>\r\n\t\t</BlueChannel>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</ChannelSelection>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (Normalize == true || Histogram == true || Gamma == true)
+    {
+      xml = sqlite3_mprintf("%s\t<ContrastEnhancement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Histogram == true)
+        {
+          xml = sqlite3_mprintf("%s\t\t<Histogram/>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+      } else if (Gamma == true)
+        {
+          xml =
+            sqlite3_mprintf("%s\t\t<GammaValue>%1.2f</GammaValue>\r\n", prev,
+                            GammaValue);
+          sqlite3_free(prev);
+          prev = xml;
+      } else
+        {
+          xml = sqlite3_mprintf("%s\t\t<Normalize/>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</ContrastEnhancement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+void RasterSymbolizerChannelRgbDialog::
+OnInsert(wxCommandEvent & WXUNUSED(event))
+{
+//
+// inserting the RasterSymbolizer into the DBMS
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  if (MainFrame->DoInsertRasterSymbolizer(xml) == true)
+    wxMessageBox(wxT
+                 ("SLD/SE RasterSymbolizer successfully registered into the DBMS"),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerChannelRgbDialog::
+OnExport(wxCommandEvent & WXUNUSED(event))
+{
+//
+// exporting the RasterSymbolizer as an external file
+//
+  int ret;
+  wxString path;
+  wxString lastDir;
+  if (RetrieveParams() == false)
+    return;
+  wxFileDialog fileDialog(this,
+                          wxT("Exporting an SLD/SE RasterSymbolizer to a file"),
+                          wxT(""), Name + wxT(".xml"),
+                          wxT("XML Document|*.xml|All files (*.*)|*.*"),
+                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      wxFileName file(fileDialog.GetPath());
+      path = file.GetPath();
+      path += file.GetPathSeparator();
+      path += file.GetName();
+      lastDir = file.GetPath();
+      path = fileDialog.GetPath();
+      FILE *out = fopen(path.ToUTF8(), "wb");
+      if (out == NULL)
+        wxMessageBox(wxT("ERROR: unable to create:\n\n\"") + path + wxT("\""),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else
+        {
+          char *xml;
+          if (MinScale == true || MaxScale == true)
+            xml = DoCreateCoverageXML();
+          else
+            xml = DoCreateSymbolizerXML();
+          fwrite(xml, 1, strlen(xml), out);
+          sqlite3_free(xml);
+          fclose(out);
+          wxMessageBox(wxT
+                       ("SLD/SE RasterSymbolizer successfully saved into:\n\n\"")
+                       + path + wxT("\""), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerChannelRgbDialog::OnCopy(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Copying the RasterSymbolizer into the Clipboard 
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  wxString XMLstring = wxString::FromUTF8(xml);
+  if (wxTheClipboard->Open())
+    {
+      wxTheClipboard->SetData(new wxTextDataObject(XMLstring));
+      wxTheClipboard->Close();
+    }
+}
+
+void RasterSymbolizerChannelRgbDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool RasterSymbolizerChannelGrayDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Normalize = false;
+  Histogram = false;
+  Gamma = false;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT
+                       ("RasterSymbolizer: ChannelSelection (single band, Grayscale)"))
+      == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void RasterSymbolizerChannelGrayDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the RasterSymbolizer Name
+  wxBoxSizer *nameSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(nameSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *nameLabel = new wxStaticText(this, wxID_STATIC, wxT("&Name:"));
+  nameSizer->Add(nameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *nameCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_NAME, wxT(""),
+                                        wxDefaultPosition, wxSize(600, 22));
+  nameSizer->Add(nameCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the RasterSymbolizer Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the RasterSymbolizer Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_ABSTRACT, wxT(""),
+                   wxDefaultPosition, wxSize(600, 60),
+                   wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the RasterSymbolizer Opacity
+  wxBoxSizer *opacitySizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacitySizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *opacityLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Opacity:"));
+  opacitySizer->Add(opacityLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSlider *opacityCtrl = new wxSlider(this, ID_SYMBOLIZER_OPACITY, 100, 0, 100,
+                                       wxDefaultPosition, wxSize(600, 45),
+                                       wxSL_HORIZONTAL | wxSL_LABELS);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// fifth row: ChannelSelection
+  wxBoxSizer *channelBoxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(channelBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *channelBox = new wxStaticBox(this, wxID_STATIC,
+                                            wxT
+                                            ("Channel Selection (first Band is #1)"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *channelSizer = new wxStaticBoxSizer(channelBox, wxVERTICAL);
+  channelBoxSizer->Add(channelSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *bandSizer = new wxBoxSizer(wxVERTICAL);
+  channelSizer->Add(bandSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *graySizer = new wxBoxSizer(wxHORIZONTAL);
+  bandSizer->Add(graySizer, 0, wxALIGN_RIGHT | wxALL, 3);
+  wxStaticText *grayLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Gray Channel is Band #"));
+  graySizer->Add(grayLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSpinCtrl *grayCtrl = new wxSpinCtrl(this, ID_SYMBOLIZER_GRAY, wxT("1"),
+                                        wxDefaultPosition, wxSize(80, 22),
+                                        wxSP_ARROW_KEYS,
+                                        1, 256, 1);
+  graySizer->Add(grayCtrl, 0, wxALIGN_RIGHT | wxALL, 0);
+// sixth row: Contrast Enhancement
+  wxBoxSizer *contrastSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(contrastSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxString contrast[4];
+  contrast[0] = wxT("&None");
+  contrast[1] = wxT("Normalize/&Stretch");
+  contrast[2] = wxT("&Histogram");
+  contrast[3] = wxT("&GammaValue");
+  wxRadioBox *contrastBox = new wxRadioBox(this, ID_SYMBOLIZER_CONTRAST,
+                                           wxT("&Contrast Enhancement Method"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize, 4,
+                                           contrast, 2,
+                                           wxRA_SPECIFY_COLS);
+  contrastSizer->Add(contrastBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  contrastBox->SetSelection(0);
+  wxBoxSizer *gammaSizer = new wxBoxSizer(wxHORIZONTAL);
+  contrastSizer->Add(gammaSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticText *gammaLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&GammaValue [x100]:"));
+  gammaSizer->Add(gammaLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSpinCtrl *gammaCtrl = new wxSpinCtrl(this, ID_SYMBOLIZER_GAMMA, wxT("100"),
+                                         wxDefaultPosition, wxSize(80, 22),
+                                         wxSP_ARROW_KEYS,
+                                         100, 500, 100);
+  gammaCtrl->Enable(false);
+  gammaSizer->Add(gammaCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// seventh row: optional Visibility Range
+  wxBoxSizer *visibilityBoxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(visibilityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *visibilityBox = new wxStaticBox(this, wxID_STATIC,
+                                               wxT("Visibility Range"),
+                                               wxDefaultPosition,
+                                               wxDefaultSize);
+  wxBoxSizer *visibilitySizer =
+    new wxStaticBoxSizer(visibilityBox, wxHORIZONTAL);
+  visibilityBoxSizer->Add(visibilitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL,
+                          5);
+  wxString range[4];
+  range[0] = wxT("&None");
+  range[1] = wxT("&Min");
+  range[2] = wxT("&Max");
+  range[3] = wxT("&Both");
+  wxRadioBox *rangeBox = new wxRadioBox(this, ID_SYMBOLIZER_MINMAX_SCALE,
+                                        wxT("&Range Type"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 4,
+                                        range, 2,
+                                        wxRA_SPECIFY_COLS);
+  visibilitySizer->Add(rangeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  rangeBox->SetSelection(0);
+  visibilitySizer->AddSpacer(20);
+  wxBoxSizer *scaleBoxSizer = new wxBoxSizer(wxVERTICAL);
+  visibilitySizer->Add(scaleBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *scaleMinSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMinSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *minScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Min Scale:"));
+  scaleMinSizer->Add(minScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *minScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MIN_SCALE, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  minScaleCtrl->Enable(false);
+  scaleMinSizer->Add(minScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *scaleMaxSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMaxSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *maxScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Max Scale:"));
+  scaleMaxSizer->Add(maxScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *maxScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MAX_SCALE, wxT("+Infinite"),
+                   wxDefaultPosition, wxSize(100, 22));
+  maxScaleCtrl->Enable(false);
+  scaleMaxSizer->Add(maxScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *insert =
+    new wxButton(this, ID_SYMBOLIZER_INSERT, wxT("&Insert into DBMS"));
+  btnBox->Add(insert, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *exp =
+    new wxButton(this, ID_SYMBOLIZER_EXPORT, wxT("&Export to file"));
+  btnBox->Add(exp, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *copy = new wxButton(this, ID_SYMBOLIZER_COPY, wxT("&Copy"));
+  btnBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerChannelGrayDialog::OnQuit);
+  Connect(ID_SYMBOLIZER_INSERT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerChannelGrayDialog::OnInsert);
+  Connect(ID_SYMBOLIZER_EXPORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerChannelGrayDialog::OnExport);
+  Connect(ID_SYMBOLIZER_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerChannelGrayDialog::OnCopy);
+  Connect(ID_SYMBOLIZER_CONTRAST, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerChannelGrayDialog::OnCmdModeChanged);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerChannelGrayDialog::OnCmdScaleChanged);
+}
+
+void RasterSymbolizerChannelGrayDialog::
+OnCmdModeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Contrast Enhancement Method selection changed
+//
+  wxRadioBox *contrastCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_CONTRAST);
+  wxSpinCtrl *gammaCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_GAMMA);
+  switch (contrastCtrl->GetSelection())
+    {
+      case 0:
+        Normalize = false;
+        Histogram = false;
+        Gamma = false;
+        gammaCtrl->Enable(false);
+        break;
+      case 1:
+        Normalize = true;
+        Histogram = false;
+        Gamma = false;
+        gammaCtrl->Enable(false);
+        break;
+      case 2:
+        Normalize = false;
+        Histogram = true;
+        Gamma = false;
+        gammaCtrl->Enable(false);
+        break;
+      case 3:
+        Normalize = false;
+        Histogram = false;
+        Gamma = true;
+        gammaCtrl->Enable(true);
+        break;
+    };
+}
+
+void RasterSymbolizerChannelGrayDialog::
+OnCmdScaleChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Visibility Range selection changed
+//
+  wxRadioBox *scaleModeCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  switch (scaleModeCtrl->GetSelection())
+    {
+      case 0:
+        MinScale = false;
+        MaxScale = false;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 1:
+        MinScale = true;
+        MaxScale = false;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 2:
+        MinScale = false;
+        MaxScale = true;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+      case 3:
+        MinScale = true;
+        MaxScale = true;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+    };
+}
+
+bool RasterSymbolizerChannelGrayDialog::RetrieveParams()
+{
+//
+// retrieving the RasterSymbolizer params 
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  Name = nameCtrl->GetValue();
+  if (Name.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the RasterSymbolizer NAME !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  Title = titleCtrl->GetValue();
+  if (Title.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer TITLE is warmly suggested\n\n");
+      msg += wxT("Do you really confirm leaving an empty (undefined) Title ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  Abstract = absCtrl->GetValue();
+  if (Abstract.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer ABSTRACT is warmly suggested\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an empty (undefined) Abstract ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_OPACITY);
+  Opacity = opacityCtrl->GetValue() / 100.0;
+  wxSpinCtrl *grayCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_GRAY);
+  GrayBand = grayCtrl->GetValue();
+  if (Gamma == true)
+    {
+      wxSpinCtrl *gammaCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_GAMMA);
+      GammaValue = gammaCtrl->GetValue() / 100.0;
+  } else
+    GammaValue = 1.0;
+  if (MinScale == true)
+    {
+      wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+      wxString value = minCtrl->GetValue();
+      if (value.ToDouble(&MinScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MinScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MaxScale == true)
+    {
+      wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+      wxString value = maxCtrl->GetValue();
+      if (value.ToDouble(&MaxScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MaxScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MinScale == true && MaxScale == true)
+    {
+      if (MinScaleDenominator >= MaxScaleDenominator)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE is always expected to be greater than MIN_SCALE !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  return true;
+}
+
+char *RasterSymbolizerChannelGrayDialog::DoCreateCoverageXML()
+{
+//
+// creating the SLD/SE (XML) code - CoverageStyle
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<CoverageStyle version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Rule>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (MinScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MinScaleDenominator>%1.2f</MinScaleDenominator>\r\n", prev,
+         MinScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MaxScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MaxScaleDenominator>%1.2f</MaxScaleDenominator>\r\n", prev,
+         MaxScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t<RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<ChannelSelection>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t\t\t<GrayChannel>\r\n\t\t\t\t\t<SourceChannelName>%d", prev,
+     GrayBand);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s</SourceChannelName>\r\n\t\t\t\t</GrayChannel>\r\n",
+                    prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t</ChannelSelection>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (Normalize == true || Histogram == true || Gamma == true)
+    {
+      xml = sqlite3_mprintf("%s\t\t\t<ContrastEnhancement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Histogram == true)
+        {
+          xml = sqlite3_mprintf("%s\t\t\t\t<Histogram/>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+      } else if (Gamma == true)
+        {
+          xml =
+            sqlite3_mprintf("%s\t\t\t\t<GammaValue>%1.2f</GammaValue>\r\n",
+                            prev, GammaValue);
+          sqlite3_free(prev);
+          prev = xml;
+      } else
+        {
+          xml = sqlite3_mprintf("%s\t\t\t\t<Normalize/>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t\t</ContrastEnhancement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</Rule>\r\n</CoverageStyle>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+char *RasterSymbolizerChannelGrayDialog::DoCreateSymbolizerXML()
+{
+//
+// creating the SLD/SE (XML) code - RasterSymbolizer
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<RasterSymbolizer version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/Symbolizer.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t<ChannelSelection>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t<GrayChannel>\r\n\t\t\t<SourceChannelName>%d", prev,
+                    GrayBand);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s</SourceChannelName>\r\n\t\t</GrayChannel>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</ChannelSelection>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (Normalize == true || Histogram == true || Gamma == true)
+    {
+      xml = sqlite3_mprintf("%s\t<ContrastEnhancement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Histogram == true)
+        {
+          xml = sqlite3_mprintf("%s\t\t<Histogram/>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+      } else if (Gamma == true)
+        {
+          xml =
+            sqlite3_mprintf("%s\t\t<GammaValue>%1.2f</GammaValue>\r\n", prev,
+                            GammaValue);
+          sqlite3_free(prev);
+          prev = xml;
+      } else
+        {
+          xml = sqlite3_mprintf("%s\t\t<Normalize/>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</ContrastEnhancement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+void RasterSymbolizerChannelGrayDialog::
+OnInsert(wxCommandEvent & WXUNUSED(event))
+{
+//
+// inserting the RasterSymbolizer into the DBMS
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  if (MainFrame->DoInsertRasterSymbolizer(xml) == true)
+    wxMessageBox(wxT
+                 ("SLD/SE RasterSymbolizer successfully registered into the DBMS"),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerChannelGrayDialog::
+OnExport(wxCommandEvent & WXUNUSED(event))
+{
+//
+// exporting the RasterSymbolizer as an external file
+//
+  int ret;
+  wxString path;
+  wxString lastDir;
+  if (RetrieveParams() == false)
+    return;
+  wxFileDialog fileDialog(this,
+                          wxT("Exporting an SLD/SE RasterSymbolizer to a file"),
+                          wxT(""), Name + wxT(".xml"),
+                          wxT("XML Document|*.xml|All files (*.*)|*.*"),
+                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      wxFileName file(fileDialog.GetPath());
+      path = file.GetPath();
+      path += file.GetPathSeparator();
+      path += file.GetName();
+      lastDir = file.GetPath();
+      path = fileDialog.GetPath();
+      FILE *out = fopen(path.ToUTF8(), "wb");
+      if (out == NULL)
+        wxMessageBox(wxT("ERROR: unable to create:\n\n\"") + path + wxT("\""),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else
+        {
+          char *xml;
+          if (MinScale == true || MaxScale == true)
+            xml = DoCreateCoverageXML();
+          else
+            xml = DoCreateSymbolizerXML();
+          fwrite(xml, 1, strlen(xml), out);
+          sqlite3_free(xml);
+          fclose(out);
+          wxMessageBox(wxT
+                       ("SLD/SE RasterSymbolizer successfully saved into:\n\n\"")
+                       + path + wxT("\""), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerChannelGrayDialog::OnCopy(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Copying the RasterSymbolizer into the Clipboard 
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  wxString XMLstring = wxString::FromUTF8(xml);
+  if (wxTheClipboard->Open())
+    {
+      wxTheClipboard->SetData(new wxTextDataObject(XMLstring));
+      wxTheClipboard->Close();
+    }
+}
+
+void RasterSymbolizerChannelGrayDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool RasterSymbolizerShadedReliefDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  MinScale = false;
+  MaxScale = false;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT
+                       ("RasterSymbolizer: Shaded Relief (brightness only)"))
+      == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void RasterSymbolizerShadedReliefDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the RasterSymbolizer Name
+  wxBoxSizer *nameSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(nameSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *nameLabel = new wxStaticText(this, wxID_STATIC, wxT("&Name:"));
+  nameSizer->Add(nameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *nameCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_NAME, wxT(""),
+                                        wxDefaultPosition, wxSize(600, 22));
+  nameSizer->Add(nameCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the RasterSymbolizer Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the RasterSymbolizer Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_ABSTRACT, wxT(""),
+                   wxDefaultPosition, wxSize(600, 60),
+                   wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the RasterSymbolizer Opacity
+  wxBoxSizer *opacitySizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacitySizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *opacityLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Opacity:"));
+  opacitySizer->Add(opacityLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSlider *opacityCtrl = new wxSlider(this, ID_SYMBOLIZER_OPACITY, 100, 0, 100,
+                                       wxDefaultPosition, wxSize(600, 45),
+                                       wxSL_HORIZONTAL | wxSL_LABELS);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// fifth row: the Relief Factor
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *shadedBoxSizer = new wxBoxSizer(wxVERTICAL);
+  miscSizer->Add(shadedBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *shadedBox = new wxStaticBox(this, wxID_STATIC,
+                                           wxT("Shaded Relief"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize);
+  wxBoxSizer *shadedSizer = new wxStaticBoxSizer(shadedBox, wxHORIZONTAL);
+  shadedBoxSizer->Add(shadedSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *reliefSizer = new wxBoxSizer(wxVERTICAL);
+  shadedSizer->Add(reliefSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *reliefLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Relief Factor:"));
+  reliefSizer->Add(reliefLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSpinCtrl *reliefCtrl = new wxSpinCtrl(this, ID_SYMBOLIZER_RELIEF, wxT(""),
+                                          wxDefaultPosition, wxSize(80, 22),
+                                          wxSP_ARROW_KEYS,
+                                          1, 200, 25);
+  reliefSizer->Add(reliefCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// sixth row: optional Visibility Range
+  miscSizer->AddSpacer(25);
+  wxBoxSizer *visibilityBoxSizer = new wxBoxSizer(wxVERTICAL);
+  miscSizer->Add(visibilityBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *visibilityBox = new wxStaticBox(this, wxID_STATIC,
+                                               wxT("Visibility Range"),
+                                               wxDefaultPosition,
+                                               wxDefaultSize);
+  wxBoxSizer *visibilitySizer =
+    new wxStaticBoxSizer(visibilityBox, wxHORIZONTAL);
+  visibilityBoxSizer->Add(visibilitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL,
+                          5);
+  wxString range[4];
+  range[0] = wxT("&None");
+  range[1] = wxT("&Min");
+  range[2] = wxT("&Max");
+  range[3] = wxT("&Both");
+  wxRadioBox *rangeBox = new wxRadioBox(this, ID_SYMBOLIZER_MINMAX_SCALE,
+                                        wxT("&Range Type"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 4,
+                                        range, 2,
+                                        wxRA_SPECIFY_COLS);
+  visibilitySizer->Add(rangeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  rangeBox->SetSelection(0);
+  visibilitySizer->AddSpacer(20);
+  wxBoxSizer *scaleBoxSizer = new wxBoxSizer(wxVERTICAL);
+  visibilitySizer->Add(scaleBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *scaleMinSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMinSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *minScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Min Scale:"));
+  scaleMinSizer->Add(minScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *minScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MIN_SCALE, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  minScaleCtrl->Enable(false);
+  scaleMinSizer->Add(minScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *scaleMaxSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMaxSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *maxScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Max Scale:"));
+  scaleMaxSizer->Add(maxScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *maxScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MAX_SCALE, wxT("+Infinite"),
+                   wxDefaultPosition, wxSize(100, 22));
+  maxScaleCtrl->Enable(false);
+  scaleMaxSizer->Add(maxScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *insert =
+    new wxButton(this, ID_SYMBOLIZER_INSERT, wxT("&Insert into DBMS"));
+  btnBox->Add(insert, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *exp =
+    new wxButton(this, ID_SYMBOLIZER_EXPORT, wxT("&Export to file"));
+  btnBox->Add(exp, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *copy = new wxButton(this, ID_SYMBOLIZER_COPY, wxT("&Copy"));
+  btnBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerShadedReliefDialog::OnQuit);
+  Connect(ID_SYMBOLIZER_INSERT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerShadedReliefDialog::OnInsert);
+  Connect(ID_SYMBOLIZER_EXPORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerShadedReliefDialog::OnExport);
+  Connect(ID_SYMBOLIZER_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerShadedReliefDialog::OnCopy);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerShadedReliefDialog::OnCmdScaleChanged);
+}
+
+bool RasterSymbolizerShadedReliefDialog::RetrieveParams()
+{
+//
+// retrieving the RasterSymbolizer params 
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  Name = nameCtrl->GetValue();
+  if (Name.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the RasterSymbolizer NAME !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  Title = titleCtrl->GetValue();
+  if (Title.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer TITLE is warmly suggested\n\n");
+      msg += wxT("Do you really confirm leaving an empty (undefined) Title ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  Abstract = absCtrl->GetValue();
+  if (Abstract.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer ABSTRACT is warmly suggested\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an empty (undefined) Abstract ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_OPACITY);
+  Opacity = opacityCtrl->GetValue() / 100.0;
+  wxSpinCtrl *reliefCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_RELIEF);
+  ReliefFactor = reliefCtrl->GetValue();
+  if (MinScale == true)
+    {
+      wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+      wxString value = minCtrl->GetValue();
+      if (value.ToDouble(&MinScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MinScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MaxScale == true)
+    {
+      wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+      wxString value = maxCtrl->GetValue();
+      if (value.ToDouble(&MaxScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MaxScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MinScale == true && MaxScale == true)
+    {
+      if (MinScaleDenominator >= MaxScaleDenominator)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE is always expected to be greater than MIN_SCALE !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  return true;
+}
+
+void RasterSymbolizerShadedReliefDialog::
+OnCmdScaleChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Visibility Range selection changed
+//
+  wxRadioBox *scaleModeCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  switch (scaleModeCtrl->GetSelection())
+    {
+      case 0:
+        MinScale = false;
+        MaxScale = false;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 1:
+        MinScale = true;
+        MaxScale = false;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 2:
+        MinScale = false;
+        MaxScale = true;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+      case 3:
+        MinScale = true;
+        MaxScale = true;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+    };
+}
+
+char *RasterSymbolizerShadedReliefDialog::DoCreateCoverageXML()
+{
+//
+// creating the SLD/SE (XML) code - CoverageStyle
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<CoverageStyle version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Rule>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (MinScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MinScaleDenominator>%1.2f</MinScaleDenominator>\r\n", prev,
+         MinScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MaxScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MaxScaleDenominator>%1.2f</MaxScaleDenominator>\r\n", prev,
+         MaxScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t<RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<ShadedRelief>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t\t\t<BrightnessOnly>1</BrightnessOnly>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t\t\t<ReliefFactor>%1.2f</ReliefFactor>\r\n", prev,
+                    ReliefFactor);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t</ShadedRelief>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</Rule>\r\n</CoverageStyle>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+char *RasterSymbolizerShadedReliefDialog::DoCreateSymbolizerXML()
+{
+//
+// creating the SLD/SE (XML) code - RasterSymbolizer
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<RasterSymbolizer version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/Symbolizer.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t<ShadedRelief>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t<BrightnessOnly>1</BrightnessOnly>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t<ReliefFactor>%1.2f</ReliefFactor>\r\n", prev,
+                    ReliefFactor);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</ShadedRelief>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+void RasterSymbolizerShadedReliefDialog::
+OnInsert(wxCommandEvent & WXUNUSED(event))
+{
+//
+// inserting the RasterSymbolizer into the DBMS
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  if (MainFrame->DoInsertRasterSymbolizer(xml) == true)
+    wxMessageBox(wxT
+                 ("SLD/SE RasterSymbolizer successfully registered into the DBMS"),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerShadedReliefDialog::
+OnExport(wxCommandEvent & WXUNUSED(event))
+{
+//
+// exporting the RasterSymbolizer as an external file
+//
+  int ret;
+  wxString path;
+  wxString lastDir;
+  if (RetrieveParams() == false)
+    return;
+  wxFileDialog fileDialog(this,
+                          wxT("Exporting an SLD/SE RasterSymbolizer to a file"),
+                          wxT(""), Name + wxT(".xml"),
+                          wxT("XML Document|*.xml|All files (*.*)|*.*"),
+                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      wxFileName file(fileDialog.GetPath());
+      path = file.GetPath();
+      path += file.GetPathSeparator();
+      path += file.GetName();
+      lastDir = file.GetPath();
+      path = fileDialog.GetPath();
+      FILE *out = fopen(path.ToUTF8(), "wb");
+      if (out == NULL)
+        wxMessageBox(wxT("ERROR: unable to create:\n\n\"") + path + wxT("\""),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else
+        {
+          char *xml;
+          if (MinScale == true || MaxScale == true)
+            xml = DoCreateCoverageXML();
+          else
+            xml = DoCreateSymbolizerXML();
+          fwrite(xml, 1, strlen(xml), out);
+          sqlite3_free(xml);
+          fclose(out);
+          wxMessageBox(wxT
+                       ("SLD/SE RasterSymbolizer successfully saved into:\n\n\"")
+                       + path + wxT("\""), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerShadedReliefDialog::
+OnCopy(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Copying the RasterSymbolizer into the Clipboard 
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  wxString XMLstring = wxString::FromUTF8(xml);
+  if (wxTheClipboard->Open())
+    {
+      wxTheClipboard->SetData(new wxTextDataObject(XMLstring));
+      wxTheClipboard->Close();
+    }
+}
+
+void RasterSymbolizerShadedReliefDialog::
+OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool ColorMapEntry::IsValidColor(wxString & color)
+{
+// testing an HexRGB color for validity
+  if (color.Len() != 7)
+    return false;
+  char hex[64];
+  strcpy(hex, color.ToUTF8());
+  if (*(hex + 0) != '#')
+    return false;
+  for (int i = 1; i <= 6; i++)
+    {
+      char x = *(hex + i);
+      if (x >= '0' && x <= '9')
+        continue;
+      if (x >= 'a' && x <= 'f')
+        continue;
+      if (x >= 'A' && x <= 'F')
+        continue;
+      return false;
+    }
+  return true;
+}
+
+unsigned char ColorMapEntry::ParseHex(unsigned char hi, unsigned char lo)
+{
+// parsing an HEX color
+  unsigned char byte;
+  switch (hi)
+    {
+      case '0':
+        byte = 16 * 0;
+        break;
+      case '1':
+        byte = 16 * 1;
+        break;
+      case '2':
+        byte = 16 * 2;
+        break;
+      case '3':
+        byte = 16 * 3;
+        break;
+      case '4':
+        byte = 16 * 4;
+        break;
+      case '5':
+        byte = 16 * 5;
+        break;
+      case '6':
+        byte = 16 * 6;
+        break;
+      case '7':
+        byte = 16 * 7;
+        break;
+      case '8':
+        byte = 16 * 8;
+        break;
+      case '9':
+        byte = 16 * 9;
+        break;
+      case 'a':
+      case 'A':
+        byte = 16 * 10;
+        break;
+      case 'b':
+      case 'B':
+        byte = 16 * 11;
+        break;
+      case 'c':
+      case 'C':
+        byte = 16 * 12;
+        break;
+      case 'd':
+      case 'D':
+        byte = 16 * 13;
+        break;
+      case 'e':
+      case 'E':
+        byte = 16 * 14;
+        break;
+      case 'f':
+      case 'F':
+        byte = 16 * 15;
+        break;
+    };
+  switch (lo)
+    {
+      case '0':
+        byte += 0;
+        break;
+      case '1':
+        byte += 1;
+        break;
+      case '2':
+        byte += 2;
+        break;
+      case '3':
+        byte += 3;
+        break;
+      case '4':
+        byte += 4;
+        break;
+      case '5':
+        byte += 5;
+        break;
+      case '6':
+        byte += 6;
+        break;
+      case '7':
+        byte += 7;
+        break;
+      case '8':
+        byte += 8;
+        break;
+      case '9':
+        byte += 9;
+        break;
+      case 'a':
+      case 'A':
+        byte += 10;
+        break;
+      case 'b':
+      case 'B':
+        byte += 11;
+        break;
+      case 'c':
+      case 'C':
+        byte += 12;
+        break;
+      case 'd':
+      case 'D':
+        byte += 13;
+        break;
+      case 'e':
+      case 'E':
+        byte += 14;
+        break;
+      case 'f':
+      case 'F':
+        byte += 15;
+        break;
+    };
+  return byte;
+}
+
+void ColorMapEntry::GetWxColor(wxString & color, wxColour & clr)
+{
+// return a wxWidger color from an HexRGB color
+  if (IsValidColor(color) == false)
+    {
+      clr = wxColour(0, 0, 0);
+      return;
+    }
+  char hex[64];
+  strcpy(hex, color.ToUTF8());
+  unsigned char red = ParseHex(*(hex + 1), *(hex + 2));
+  unsigned char green = ParseHex(*(hex + 3), *(hex + 4));
+  unsigned char blue = ParseHex(*(hex + 5), *(hex + 6));
+  clr = wxColour(red, green, blue);
+}
+
+ColorMapCategorize::~ColorMapCategorize()
+{
+// dtor
+  ColorMapEntry *pE;
+  ColorMapEntry *pEn;
+  pE = First;
+  while (pE != NULL)
+    {
+      pEn = pE->GetNext();
+      delete pE;
+      pE = pEn;
+    }
+}
+
+void ColorMapCategorize::Add(double value, wxString & color)
+{
+// adding a new Entry into the Map by searching the appropriate position
+// or updating an already existing Entry
+  ColorMapEntry *pE;
+  ColorMapEntry *pEnew;
+  pE = First;
+  while (pE != NULL)
+    {
+      if (pE->GetValue() == value)
+        {
+          // updating an already defined Entry
+          pE->SetColor(color);
+          return;
+        }
+      pE = pE->GetNext();
+    }
+
+// inserting a new Entry
+  bool is_first = false;
+  if (First == NULL)
+    is_first = true;
+  else if (value < First->GetValue())
+    is_first = true;
+  if (is_first == true)
+    {
+      // inserting at the beginning of the Map
+      pEnew = new ColorMapEntry(value, color);
+      if (First == NULL)
+        {
+          First = pEnew;
+          Last = pEnew;
+          return;
+        }
+      First->SetPrev(pEnew);
+      pEnew->SetNext(First);
+      First = pEnew;
+      return;
+    }
+
+  pE = First;
+  while (pE != NULL)
+    {
+      // searching the appropriate position into the Map
+      if (value < pE->GetValue())
+        {
+          pEnew = new ColorMapEntry(value, color);
+          pE->GetPrev()->SetNext(pEnew);
+          pEnew->SetPrev(pE->GetPrev());
+          pEnew->SetNext(pE);
+          pE->SetPrev(pEnew);
+          return;
+        }
+      pE = pE->GetNext();
+    }
+
+// last item
+  pEnew = new ColorMapEntry(value, color);
+  pEnew->SetPrev(Last);
+  Last->SetNext(pEnew);
+  Last = pEnew;
+}
+
+void ColorMapCategorize::Remove(double value)
+{
+// removing an Entry from the Map
+  ColorMapEntry *pE;
+  pE = First;
+  while (pE != NULL)
+    {
+      if (pE->GetValue() == value)
+        {
+          if (pE == First && pE == Last)
+            {
+              // removing the unique Entry
+              First = NULL;
+              Last = NULL;
+              delete pE;
+          } else if (pE == First)
+            {
+              // removing the first Entry
+              pE->GetNext()->SetPrev(NULL);
+              First = pE->GetNext();
+              delete pE;
+          } else if (pE == Last)
+            {
+              // removing the last Entry
+              pE->GetPrev()->SetNext(NULL);
+              Last = pE->GetPrev();
+              delete pE;
+          } else
+            {
+              // removing any other Entry
+              pE->GetPrev()->SetNext(pE->GetNext());
+              pE->GetNext()->SetPrev(pE->GetPrev());
+              delete pE;
+            }
+          break;
+        }
+      pE = pE->GetNext();
+    }
+}
+
+bool RasterSymbolizerCategorizeDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  ShadedRelief = false;
+  MinScale = false;
+  MaxScale = false;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT
+                       ("RasterSymbolizer: Color Map - Categorize")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void RasterSymbolizerCategorizeDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the RasterSymbolizer Name
+  wxBoxSizer *nameSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(nameSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *nameLabel = new wxStaticText(this, wxID_STATIC, wxT("&Name:"));
+  nameSizer->Add(nameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *nameCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_NAME, wxT(""),
+                                        wxDefaultPosition, wxSize(600, 22));
+  nameSizer->Add(nameCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the RasterSymbolizer Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the RasterSymbolizer Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_ABSTRACT, wxT(""),
+                   wxDefaultPosition, wxSize(600, 60),
+                   wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the RasterSymbolizer Opacity
+  wxBoxSizer *opacitySizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacitySizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *opacityLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Opacity:"));
+  opacitySizer->Add(opacityLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSlider *opacityCtrl = new wxSlider(this, ID_SYMBOLIZER_OPACITY, 100, 0, 100,
+                                       wxDefaultPosition, wxSize(600, 45),
+                                       wxSL_HORIZONTAL | wxSL_LABELS);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// fourth row: GRID to show the Color Map
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Color Map"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_SYMBOLIZER_MAP, wxDefaultPosition, wxSize(380, 250),
+               wxALWAYS_SHOW_SB);
+  GridCtrl->CreateGrid(1, 4, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Min Value"));
+  GridCtrl->SetColLabelValue(1, wxT("Max Value"));
+  GridCtrl->SetColLabelValue(2, wxT("Color"));
+  GridCtrl->SetColLabelValue(3, wxT("Sample"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  wxString cell = wxT("-Infinite");
+  GridCtrl->SetCellValue(0, 0, cell);
+  GridCtrl->SetCellAlignment(0, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+  cell = wxT("+Infinite");
+  GridCtrl->SetCellValue(0, 1, cell);
+  GridCtrl->SetCellAlignment(0, 1, wxALIGN_RIGHT, wxALIGN_CENTRE);
+  GridCtrl->SetCellValue(0, 2, Map.GetFirstColor());
+  wxColour color;
+  ColorMapEntry::GetWxColor(Map.GetFirstColor(), color);
+  GridCtrl->SetCellBackgroundColour(0, 3, color);
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// extra Map items
+  wxBoxSizer *extraBoxSizer = new wxBoxSizer(wxVERTICAL);
+  gridSizer->Add(extraBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *entryBox = new wxStaticBox(this, wxID_STATIC,
+                                          wxT("Map Entry"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *entrySizer = new wxStaticBoxSizer(entryBox, wxHORIZONTAL);
+  extraBoxSizer->Add(entrySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *entry1Sizer = new wxBoxSizer(wxVERTICAL);
+  entrySizer->Add(entry1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxBoxSizer *entry2Sizer = new wxBoxSizer(wxVERTICAL);
+  entrySizer->Add(entry2Sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *valueSizer = new wxBoxSizer(wxHORIZONTAL);
+  entry1Sizer->Add(valueSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *valueLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Threshold:"));
+  valueSizer->Add(valueLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxTextCtrl *valueCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_VALUE, wxT("0.00"),
+                                         wxDefaultPosition, wxSize(100, 22));
+  valueSizer->Add(valueCtrl, 0, wxALIGN_RIGHT | wxALL, 2);
+  wxBoxSizer *colorSizer = new wxBoxSizer(wxHORIZONTAL);
+  entry1Sizer->Add(colorSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *colorLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Color:"));
+  colorSizer->Add(colorLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxTextCtrl *colorCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_COLOR, wxT("#000000"),
+                   wxDefaultPosition, wxSize(100, 22));
+  colorSizer->Add(colorCtrl, 0, wxALIGN_RIGHT | wxALL, 2);
+  wxButton *add = new wxButton(this, ID_SYMBOLIZER_ADD, wxT("&Update Map"));
+  entry2Sizer->Add(add, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxStaticBox *pickerBox = new wxStaticBox(this, wxID_STATIC,
+                                           wxT("Color Picker"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize,
+                                           wxTE_READONLY);
+  wxBoxSizer *pickerSizer = new wxStaticBoxSizer(pickerBox, wxHORIZONTAL);
+  extraBoxSizer->Add(pickerSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxButton *pick =
+    new wxButton(this, ID_SYMBOLIZER_PICKER_BTN, wxT("&Pick a color"));
+  pickerSizer->Add(pick, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxTextCtrl *pickerCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_PICKER_HEX, wxT(""),
+                   wxDefaultPosition, wxSize(100, 22));
+  pickerSizer->Add(pickerCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+// sixth row: optional Shaded Relief
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *shadedBoxSizer = new wxBoxSizer(wxVERTICAL);
+  miscSizer->Add(shadedBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *shadedBox = new wxStaticBox(this, wxID_STATIC,
+                                           wxT("Shaded Relief"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize);
+  wxBoxSizer *shadedSizer = new wxStaticBoxSizer(shadedBox, wxHORIZONTAL);
+  shadedBoxSizer->Add(shadedSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *reliefSizer = new wxBoxSizer(wxVERTICAL);
+  shadedSizer->Add(reliefSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxCheckBox *shadedCtrl = new wxCheckBox(this, ID_SYMBOLIZER_SHADED,
+                                          wxT("Shaded Relief"),
+                                          wxDefaultPosition, wxDefaultSize);
+  reliefSizer->Add(shadedCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *relief2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  reliefSizer->Add(relief2Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *reliefLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Relief Factor:"));
+  relief2Sizer->Add(reliefLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSpinCtrl *reliefCtrl = new wxSpinCtrl(this, ID_SYMBOLIZER_RELIEF, wxT(""),
+                                          wxDefaultPosition, wxSize(80, 22),
+                                          wxSP_ARROW_KEYS,
+                                          0, 0, 0);
+  reliefCtrl->Enable(false);
+  relief2Sizer->Add(reliefCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// seventh row: optional Visibility Range
+  miscSizer->AddSpacer(75);
+  wxBoxSizer *visibilityBoxSizer = new wxBoxSizer(wxVERTICAL);
+  miscSizer->Add(visibilityBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *visibilityBox = new wxStaticBox(this, wxID_STATIC,
+                                               wxT("Visibility Range"),
+                                               wxDefaultPosition,
+                                               wxDefaultSize);
+  wxBoxSizer *visibilitySizer =
+    new wxStaticBoxSizer(visibilityBox, wxHORIZONTAL);
+  visibilityBoxSizer->Add(visibilitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL,
+                          5);
+  wxString range[4];
+  range[0] = wxT("&None");
+  range[1] = wxT("&Min");
+  range[2] = wxT("&Max");
+  range[3] = wxT("&Both");
+  wxRadioBox *rangeBox = new wxRadioBox(this, ID_SYMBOLIZER_MINMAX_SCALE,
+                                        wxT("&Range Type"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 4,
+                                        range, 2,
+                                        wxRA_SPECIFY_COLS);
+  visibilitySizer->Add(rangeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  rangeBox->SetSelection(0);
+  visibilitySizer->AddSpacer(20);
+  wxBoxSizer *scaleBoxSizer = new wxBoxSizer(wxVERTICAL);
+  visibilitySizer->Add(scaleBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *scaleMinSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMinSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *minScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Min Scale:"));
+  scaleMinSizer->Add(minScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *minScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MIN_SCALE, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  minScaleCtrl->Enable(false);
+  scaleMinSizer->Add(minScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *scaleMaxSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMaxSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *maxScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Max Scale:"));
+  scaleMaxSizer->Add(maxScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *maxScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MAX_SCALE, wxT("+Infinite"),
+                   wxDefaultPosition, wxSize(100, 22));
+  maxScaleCtrl->Enable(false);
+  scaleMaxSizer->Add(maxScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *insert =
+    new wxButton(this, ID_SYMBOLIZER_INSERT, wxT("&Insert into DBMS"));
+  btnBox->Add(insert, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *exp =
+    new wxButton(this, ID_SYMBOLIZER_EXPORT, wxT("&Export to file"));
+  btnBox->Add(exp, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *copy =
+    new wxButton(this, ID_SYMBOLIZER_COPY, wxT("&Export to file"));
+  btnBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerCategorizeDialog::OnQuit);
+  Connect(ID_SYMBOLIZER_INSERT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerCategorizeDialog::OnInsert);
+  Connect(ID_SYMBOLIZER_EXPORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerCategorizeDialog::OnExport);
+  Connect(ID_SYMBOLIZER_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerCategorizeDialog::OnCopy);
+  Connect(ID_SYMBOLIZER_SHADED, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerCategorizeDialog::OnShadedChanged);
+  Connect(ID_SYMBOLIZER_ADD, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerCategorizeDialog::OnCmdAdd);
+  Connect(ID_SYMBOLIZER_REMOVE, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerCategorizeDialog::OnCmdRemove);
+  Connect(ID_SYMBOLIZER_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerCategorizeDialog::OnCmdColorPicker);
+  Connect(wxID_ANY, wxEVT_GRID_CELL_RIGHT_CLICK,
+          (wxObjectEventFunction) &
+          RasterSymbolizerCategorizeDialog::OnRightClick);
+  Connect(wxID_ANY, wxEVT_GRID_SELECT_CELL,
+          (wxObjectEventFunction) &
+          RasterSymbolizerCategorizeDialog::OnCellSelected);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerCategorizeDialog::OnCmdScaleChanged);
+}
+
+void RasterSymbolizerCategorizeDialog::
+OnCmdScaleChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Visibility Range selection changed
+//
+  wxRadioBox *scaleModeCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  switch (scaleModeCtrl->GetSelection())
+    {
+      case 0:
+        MinScale = false;
+        MaxScale = false;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 1:
+        MinScale = true;
+        MaxScale = false;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 2:
+        MinScale = false;
+        MaxScale = true;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+      case 3:
+        MinScale = true;
+        MaxScale = true;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+    };
+}
+
+void RasterSymbolizerCategorizeDialog::RefreshGrid()
+{
+//
+// refreshing the Grid
+//
+  int tot_rows = GridCtrl->GetNumberRows();
+  GridCtrl->DeleteRows(0, tot_rows);
+  int count = 1;
+  ColorMapEntry *pE = Map.GetFirst();
+  while (pE)
+    {
+      // counting how many lines are there
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl->AppendRows(count);
+  count = 1;
+  char dummy[1024];
+  wxString cell;
+  wxString last = wxT("-Infinite");
+  GridCtrl->SetCellValue(0, 0, last);
+  GridCtrl->SetCellAlignment(0, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+  pE = Map.GetFirst();
+  if (pE != NULL)
+    {
+      sprintf(dummy, "%1.6f", pE->GetValue());
+      cell = wxString::FromUTF8(dummy);
+  } else
+    cell = wxT("+Infinite");
+  GridCtrl->SetCellValue(0, 1, cell);
+  last = cell;
+  GridCtrl->SetCellAlignment(0, 1, wxALIGN_RIGHT, wxALIGN_CENTRE);
+  GridCtrl->SetCellValue(0, 2, Map.GetFirstColor());
+  wxColour color;
+  ColorMapEntry::GetWxColor(Map.GetFirstColor(), color);
+  GridCtrl->SetCellBackgroundColour(0, 3, color);
+  pE = Map.GetFirst();
+  while (pE)
+    {
+      // feeding grid rows
+      GridCtrl->SetCellValue(count, 0, last);
+      GridCtrl->SetCellAlignment(count, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      ColorMapEntry *pEn = pE->GetNext();
+      if (pEn == NULL)
+        cell = wxT("+Infinite");
+      else
+        {
+          sprintf(dummy, "%1.6f", pEn->GetValue());
+          cell = wxString::FromUTF8(dummy);
+        }
+      GridCtrl->SetCellValue(count, 1, cell);
+      last = cell;
+      GridCtrl->SetCellAlignment(count, 1, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 2, pE->GetColor());
+      ColorMapEntry::GetWxColor(pE->GetColor(), color);
+      GridCtrl->SetCellBackgroundColour(count, 3, color);
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl->AutoSizeColumns();
+}
+
+void RasterSymbolizerCategorizeDialog::OnCellSelected(wxGridEvent & event)
+{
+//
+// cell selection changed
+//
+  CurrentRow = event.GetRow();
+  wxString value = GridCtrl->GetCellValue(CurrentRow, 0);
+  wxString color = GridCtrl->GetCellValue(CurrentRow, 2);
+  wxTextCtrl *valueCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_VALUE);
+  valueCtrl->SetValue(value);
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR);
+  colorCtrl->SetValue(color);
+  if (CurrentRow == 0)
+    valueCtrl->Enable(false);
+}
+
+void RasterSymbolizerCategorizeDialog::OnRightClick(wxGridEvent & event)
+{
+//
+// right click on some cell [mouse action]
+//
+  wxMenu menu;
+  wxMenuItem *menuItem;
+  wxPoint pt = event.GetPosition();
+  CurrentRow = event.GetRow();
+  if (CurrentRow == 0)
+    return;
+  GridCtrl->SelectRow(CurrentRow);
+  wxString value = GridCtrl->GetCellValue(CurrentRow, 0);
+  double val;
+  value.ToDouble(&val);
+  CurrentValue = val;
+  menuItem = new wxMenuItem(&menu, ID_SYMBOLIZER_REMOVE, wxT("&Remove Entry"));
+  menu.Append(menuItem);
+  GridCtrl->PopupMenu(&menu, pt);
+}
+
+void RasterSymbolizerCategorizeDialog::
+OnCmdAdd(wxCommandEvent & WXUNUSED(event))
+{
+//
+// adding a new Map Entry
+//
+  wxTextCtrl *valueCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_VALUE);
+  wxString value = valueCtrl->GetValue();
+  double val;
+  if (valueCtrl->IsEnabled() == true)
+    {
+      if (value.ToDouble(&val) != true)
+        {
+          wxMessageBox(wxT
+                       ("VALUE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return;
+        }
+    }
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR);
+  wxString color = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(color) != true)
+    {
+      wxMessageBox(wxT
+                   ("COLOR isn't a valid HexRGB color !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (valueCtrl->IsEnabled() == true)
+    Map.Add(val, color);
+  else
+    Map.SetFirstColor(color);
+  RefreshGrid();
+  valueCtrl->SetValue(wxT(""));
+  valueCtrl->Enable(true);
+  colorCtrl->SetValue(wxT(""));
+}
+
+void RasterSymbolizerCategorizeDialog::
+OnCmdRemove(wxCommandEvent & WXUNUSED(event))
+{
+//
+// removing a Map Entry
+//
+  Map.Remove(CurrentValue);
+  RefreshGrid();
+}
+
+void RasterSymbolizerCategorizeDialog::
+OnShadedChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// changed Shaded Relief (on/off): 
+//
+  wxCheckBox *shadedCtrl = (wxCheckBox *) FindWindow(ID_SYMBOLIZER_SHADED);
+  wxSpinCtrl *reliefCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_RELIEF);
+  if (shadedCtrl->IsChecked() == true)
+    {
+      reliefCtrl->SetRange(1, 200);
+      reliefCtrl->SetValue(25);
+      reliefCtrl->Enable(true);
+      ShadedRelief = true;
+  } else
+    {
+      reliefCtrl->SetRange(0, 0);
+      reliefCtrl->SetValue(0);
+      reliefCtrl->Enable(false);
+      ShadedRelief = false;
+    }
+}
+
+void RasterSymbolizerCategorizeDialog::
+OnCmdColorPicker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *pickerCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_PICKER_HEX);
+  wxColour clr = wxNullColour;
+  wxString str = pickerCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      pickerCtrl->SetValue(str);
+    }
+}
+
+bool RasterSymbolizerCategorizeDialog::RetrieveParams()
+{
+//
+// retrieving the RasterSymbolizer params 
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  Name = nameCtrl->GetValue();
+  if (Name.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the RasterSymbolizer NAME !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  Title = titleCtrl->GetValue();
+  if (Title.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer TITLE is warmly suggested\n\n");
+      msg += wxT("Do you really confirm leaving an empty (undefined) Title ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  Abstract = absCtrl->GetValue();
+  if (Abstract.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer ABSTRACT is warmly suggested\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an empty (undefined) Abstract ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_OPACITY);
+  Opacity = opacityCtrl->GetValue() / 100.0;
+  if (ShadedRelief == true)
+    {
+      wxSpinCtrl *reliefCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_RELIEF);
+      ReliefFactor = reliefCtrl->GetValue();
+    }
+  if (MinScale == true)
+    {
+      wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+      wxString value = minCtrl->GetValue();
+      if (value.ToDouble(&MinScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MinScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MaxScale == true)
+    {
+      wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+      wxString value = maxCtrl->GetValue();
+      if (value.ToDouble(&MaxScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MaxScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MinScale == true && MaxScale == true)
+    {
+      if (MinScaleDenominator >= MaxScaleDenominator)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE is always expected to be greater than MIN_SCALE !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  return true;
+}
+
+char *RasterSymbolizerCategorizeDialog::DoCreateCoverageXML()
+{
+//
+// creating the SLD/SE (XML) code - CoverageStyle
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<CoverageStyle version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Rule>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (MinScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MinScaleDenominator>%1.2f</MinScaleDenominator>\r\n", prev,
+         MinScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MaxScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MaxScaleDenominator>%1.2f</MaxScaleDenominator>\r\n", prev,
+         MaxScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t<RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t<ColorMap>\r\n\t\t\t\t<Categorize fallbackValue=\"#ffffff\">\r\n",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t\t\t\t<LookupValue>Rasterdata</LookupValue>\r\n",
+                    prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Map.GetFirstColor().ToUTF8()) + 1];
+  strcpy(str, Map.GetFirstColor().ToUTF8());
+  xml = sqlite3_mprintf("%s\t\t\t\t\t<Value>%s</Value>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  ColorMapEntry *pE = Map.GetFirst();
+  while (pE != NULL)
+    {
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t\t<Threshold>%1.6f</Threshold>\r\n", prev,
+                        pE->GetValue());
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(pE->GetColor().ToUTF8()) + 1];
+      strcpy(str, pE->GetColor().ToUTF8());
+      xml = sqlite3_mprintf("%s\t\t\t\t\t<Value>%s</Value>\r\n", prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      pE = pE->GetNext();
+    }
+  xml =
+    sqlite3_mprintf("%s\t\t\t\t</Categorize>\r\n\t\t\t</ColorMap>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (ShadedRelief == true)
+    {
+      xml = sqlite3_mprintf("%s\t\t\t<ShadedRelief>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t<ReliefFactor>%1.2f</ReliefFactor>\r\n",
+                        prev, ReliefFactor);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t\t</ShadedRelief>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</Rule>\r\n</CoverageStyle>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+char *RasterSymbolizerCategorizeDialog::DoCreateSymbolizerXML()
+{
+//
+// creating the SLD/SE (XML) code - RasterSymbolizer
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<RasterSymbolizer version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/Symbolizer.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t<ColorMap>\r\n\t\t<Categorize fallbackValue=\"#ffffff\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t\t<LookupValue>Rasterdata</LookupValue>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Map.GetFirstColor().ToUTF8()) + 1];
+  strcpy(str, Map.GetFirstColor().ToUTF8());
+  xml = sqlite3_mprintf("%s\t\t\t<Value>%s</Value>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  ColorMapEntry *pE = Map.GetFirst();
+  while (pE != NULL)
+    {
+      xml =
+        sqlite3_mprintf("%s\t\t\t<Threshold>%1.6f</Threshold>\r\n", prev,
+                        pE->GetValue());
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(pE->GetColor().ToUTF8()) + 1];
+      strcpy(str, pE->GetColor().ToUTF8());
+      xml = sqlite3_mprintf("%s\t\t\t<Value>%s</Value>\r\n", prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      pE = pE->GetNext();
+    }
+  xml = sqlite3_mprintf("%s\t\t</Categorize>\r\n\t</ColorMap>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (ShadedRelief == true)
+    {
+      xml = sqlite3_mprintf("%s\t<ShadedRelief>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t<ReliefFactor>%1.2f</ReliefFactor>\r\n", prev,
+                        ReliefFactor);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t</ShadedRelief>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+void RasterSymbolizerCategorizeDialog::
+OnInsert(wxCommandEvent & WXUNUSED(event))
+{
+//
+// inserting the RasterSymbolizer into the DBMS
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  if (MainFrame->DoInsertRasterSymbolizer(xml) == true)
+    wxMessageBox(wxT
+                 ("SLD/SE RasterSymbolizer successfully registered into the DBMS"),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerCategorizeDialog::
+OnExport(wxCommandEvent & WXUNUSED(event))
+{
+//
+// exporting the RasterSymbolizer as an external file
+//
+  int ret;
+  wxString path;
+  wxString lastDir;
+  if (RetrieveParams() == false)
+    return;
+  wxFileDialog fileDialog(this,
+                          wxT("Exporting an SLD/SE RasterSymbolizer to a file"),
+                          wxT(""), Name + wxT(".xml"),
+                          wxT("XML Document|*.xml|All files (*.*)|*.*"),
+                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      wxFileName file(fileDialog.GetPath());
+      path = file.GetPath();
+      path += file.GetPathSeparator();
+      path += file.GetName();
+      lastDir = file.GetPath();
+      path = fileDialog.GetPath();
+      FILE *out = fopen(path.ToUTF8(), "wb");
+      if (out == NULL)
+        wxMessageBox(wxT("ERROR: unable to create:\n\n\"") + path + wxT("\""),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else
+        {
+          char *xml;
+          if (MinScale == true || MaxScale == true)
+            xml = DoCreateCoverageXML();
+          else
+            xml = DoCreateSymbolizerXML();
+          fwrite(xml, 1, strlen(xml), out);
+          sqlite3_free(xml);
+          fclose(out);
+          wxMessageBox(wxT
+                       ("SLD/SE RasterSymbolizer successfully saved into:\n\n\"")
+                       + path + wxT("\""), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerCategorizeDialog::OnCopy(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Copying the RasterSymbolizer into the Clipboard 
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  wxString XMLstring = wxString::FromUTF8(xml);
+  if (wxTheClipboard->Open())
+    {
+      wxTheClipboard->SetData(new wxTextDataObject(XMLstring));
+      wxTheClipboard->Close();
+    }
+}
+
+void RasterSymbolizerCategorizeDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+ColorMapInterpolate::~ColorMapInterpolate()
+{
+// dtor
+  ColorMapEntry *pE;
+  ColorMapEntry *pEn;
+  pE = First;
+  while (pE != NULL)
+    {
+      pEn = pE->GetNext();
+      delete pE;
+      pE = pEn;
+    }
+}
+
+void ColorMapInterpolate::Add(double value, wxString & color)
+{
+// adding a new Entry into the Map by searching the appropriate position
+// or updating an already existing Entry
+  ColorMapEntry *pE;
+  ColorMapEntry *pEnew;
+  pE = First;
+  while (pE != NULL)
+    {
+      if (pE->GetValue() == value)
+        {
+          // updating an already defined Entry
+          pE->SetColor(color);
+          return;
+        }
+      pE = pE->GetNext();
+    }
+
+// inserting a new Entry
+  bool is_first = false;
+  if (First == NULL)
+    is_first = true;
+  else if (value < First->GetValue())
+    is_first = true;
+  if (is_first == true)
+    {
+      // inserting at the beginning of the Map
+      pEnew = new ColorMapEntry(value, color);
+      if (First == NULL)
+        {
+          First = pEnew;
+          Last = pEnew;
+          return;
+        }
+      First->SetPrev(pEnew);
+      pEnew->SetNext(First);
+      First = pEnew;
+      return;
+    }
+
+  pE = First;
+  while (pE != NULL)
+    {
+      // searching the appropriate position into the Map
+      if (value < pE->GetValue())
+        {
+          pEnew = new ColorMapEntry(value, color);
+          pE->GetPrev()->SetNext(pEnew);
+          pEnew->SetPrev(pE->GetPrev());
+          pEnew->SetNext(pE);
+          pE->SetPrev(pEnew);
+          return;
+        }
+      pE = pE->GetNext();
+    }
+
+// last item
+  pEnew = new ColorMapEntry(value, color);
+  pEnew->SetPrev(Last);
+  Last->SetNext(pEnew);
+  Last = pEnew;
+}
+
+void ColorMapInterpolate::Remove(double value)
+{
+// removing an Entry from the Map
+  ColorMapEntry *pE;
+  pE = First;
+  while (pE != NULL)
+    {
+      if (pE->GetValue() == value)
+        {
+          if (pE == First && pE == Last)
+            {
+              // removing the unique Entry
+              First = NULL;
+              Last = NULL;
+              delete pE;
+          } else if (pE == First)
+            {
+              // removing the first Entry
+              pE->GetNext()->SetPrev(NULL);
+              First = pE->GetNext();
+              delete pE;
+          } else if (pE == Last)
+            {
+              // removing the last Entry
+              pE->GetPrev()->SetNext(NULL);
+              Last = pE->GetPrev();
+              delete pE;
+          } else
+            {
+              // removing any other Entry
+              pE->GetPrev()->SetNext(pE->GetNext());
+              pE->GetNext()->SetPrev(pE->GetPrev());
+              delete pE;
+            }
+          break;
+        }
+      pE = pE->GetNext();
+    }
+}
+
+bool RasterSymbolizerInterpolateDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Fallback = wxT("#ffffff");
+  ShadedRelief = false;
+  MinScale = false;
+  MaxScale = false;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT
+                       ("RasterSymbolizer: Color Map - Interpolate")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void RasterSymbolizerInterpolateDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the RasterSymbolizer Name
+  wxBoxSizer *nameSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(nameSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *nameLabel = new wxStaticText(this, wxID_STATIC, wxT("&Name:"));
+  nameSizer->Add(nameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *nameCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_NAME, wxT(""),
+                                        wxDefaultPosition, wxSize(600, 22));
+  nameSizer->Add(nameCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the RasterSymbolizer Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the RasterSymbolizer Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_ABSTRACT, wxT(""),
+                   wxDefaultPosition, wxSize(600, 60),
+                   wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the RasterSymbolizer Opacity
+  wxBoxSizer *opacitySizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacitySizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *opacityLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Opacity:"));
+  opacitySizer->Add(opacityLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSlider *opacityCtrl = new wxSlider(this, ID_SYMBOLIZER_OPACITY, 100, 0, 100,
+                                       wxDefaultPosition, wxSize(600, 45),
+                                       wxSL_HORIZONTAL | wxSL_LABELS);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// fourth row: GRID to show the Color Map
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Color Map"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_SYMBOLIZER_MAP, wxDefaultPosition, wxSize(280, 250),
+               wxALWAYS_SHOW_SB);
+  GridCtrl->CreateGrid(1, 3, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Value"));
+  GridCtrl->SetColLabelValue(1, wxT("Color"));
+  GridCtrl->SetColLabelValue(2, wxT("Sample"));
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// extra Map items
+  wxBoxSizer *extraBoxSizer = new wxBoxSizer(wxVERTICAL);
+  gridSizer->Add(extraBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *baseBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Fallback Color"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *baseSizer = new wxStaticBoxSizer(baseBox, wxHORIZONTAL);
+  extraBoxSizer->Add(baseSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *fallbackSizer = new wxBoxSizer(wxHORIZONTAL);
+  baseSizer->Add(fallbackSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *fallbackCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_FALLBACK, Fallback,
+                   wxDefaultPosition, wxSize(100, 22));
+  fallbackSizer->Add(fallbackCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxStaticBox *entryBox = new wxStaticBox(this, wxID_STATIC,
+                                          wxT("Color Map Entry"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *entrySizer = new wxStaticBoxSizer(entryBox, wxHORIZONTAL);
+  extraBoxSizer->Add(entrySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *entry1Sizer = new wxBoxSizer(wxVERTICAL);
+  entrySizer->Add(entry1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxBoxSizer *entry2Sizer = new wxBoxSizer(wxVERTICAL);
+  entrySizer->Add(entry2Sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *valueSizer = new wxBoxSizer(wxHORIZONTAL);
+  entry1Sizer->Add(valueSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *valueLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Value:"));
+  valueSizer->Add(valueLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxTextCtrl *valueCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_VALUE, wxT("0.00"),
+                                         wxDefaultPosition, wxSize(100, 22));
+  valueSizer->Add(valueCtrl, 0, wxALIGN_RIGHT | wxALL, 2);
+  wxBoxSizer *colorSizer = new wxBoxSizer(wxHORIZONTAL);
+  entry1Sizer->Add(colorSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *colorLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Color:"));
+  colorSizer->Add(colorLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxTextCtrl *colorCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_COLOR, wxT("#000000"),
+                   wxDefaultPosition, wxSize(100, 22));
+  colorSizer->Add(colorCtrl, 0, wxALIGN_RIGHT | wxALL, 2);
+  wxButton *add = new wxButton(this, ID_SYMBOLIZER_ADD, wxT("&Update Map"));
+  entry2Sizer->Add(add, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxStaticBox *pickerBox = new wxStaticBox(this, wxID_STATIC,
+                                           wxT("Color Picker"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize,
+                                           wxTE_READONLY);
+  wxBoxSizer *pickerSizer = new wxStaticBoxSizer(pickerBox, wxHORIZONTAL);
+  extraBoxSizer->Add(pickerSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxButton *pick =
+    new wxButton(this, ID_SYMBOLIZER_PICKER_BTN, wxT("&Pick a color"));
+  pickerSizer->Add(pick, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxTextCtrl *pickerCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_PICKER_HEX, wxT(""),
+                   wxDefaultPosition, wxSize(100, 22));
+  pickerSizer->Add(pickerCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+// sixth row: optional Shaded Relief
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *shadedBoxSizer = new wxBoxSizer(wxVERTICAL);
+  miscSizer->Add(shadedBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *shadedBox = new wxStaticBox(this, wxID_STATIC,
+                                           wxT("Shaded Relief"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize);
+  wxBoxSizer *shadedSizer = new wxStaticBoxSizer(shadedBox, wxHORIZONTAL);
+  shadedBoxSizer->Add(shadedSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *reliefSizer = new wxBoxSizer(wxVERTICAL);
+  shadedSizer->Add(reliefSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxCheckBox *shadedCtrl = new wxCheckBox(this, ID_SYMBOLIZER_SHADED,
+                                          wxT("Shaded Relief"),
+                                          wxDefaultPosition, wxDefaultSize);
+  reliefSizer->Add(shadedCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *relief2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  reliefSizer->Add(relief2Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *reliefLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Relief Factor:"));
+  relief2Sizer->Add(reliefLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSpinCtrl *reliefCtrl = new wxSpinCtrl(this, ID_SYMBOLIZER_RELIEF, wxT(""),
+                                          wxDefaultPosition, wxSize(80, 22),
+                                          wxSP_ARROW_KEYS,
+                                          0, 0, 0);
+  reliefCtrl->Enable(false);
+  relief2Sizer->Add(reliefCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// seventh row: optional Visibility Range
+  miscSizer->AddSpacer(50);
+  wxBoxSizer *visibilityBoxSizer = new wxBoxSizer(wxVERTICAL);
+  miscSizer->Add(visibilityBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *visibilityBox = new wxStaticBox(this, wxID_STATIC,
+                                               wxT("Visibility Range"),
+                                               wxDefaultPosition,
+                                               wxDefaultSize);
+  wxBoxSizer *visibilitySizer =
+    new wxStaticBoxSizer(visibilityBox, wxHORIZONTAL);
+  visibilityBoxSizer->Add(visibilitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL,
+                          5);
+  wxString range[4];
+  range[0] = wxT("&None");
+  range[1] = wxT("&Min");
+  range[2] = wxT("&Max");
+  range[3] = wxT("&Both");
+  wxRadioBox *rangeBox = new wxRadioBox(this, ID_SYMBOLIZER_MINMAX_SCALE,
+                                        wxT("&Range Type"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 4,
+                                        range, 2,
+                                        wxRA_SPECIFY_COLS);
+  visibilitySizer->Add(rangeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  rangeBox->SetSelection(0);
+  visibilitySizer->AddSpacer(20);
+  wxBoxSizer *scaleBoxSizer = new wxBoxSizer(wxVERTICAL);
+  visibilitySizer->Add(scaleBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *scaleMinSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMinSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *minScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Min Scale:"));
+  scaleMinSizer->Add(minScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *minScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MIN_SCALE, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  minScaleCtrl->Enable(false);
+  scaleMinSizer->Add(minScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *scaleMaxSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMaxSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *maxScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Max Scale:"));
+  scaleMaxSizer->Add(maxScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *maxScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MAX_SCALE, wxT("+Infinite"),
+                   wxDefaultPosition, wxSize(100, 22));
+  maxScaleCtrl->Enable(false);
+  scaleMaxSizer->Add(maxScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *insert =
+    new wxButton(this, ID_SYMBOLIZER_INSERT, wxT("&Insert into DBMS"));
+  btnBox->Add(insert, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *exp =
+    new wxButton(this, ID_SYMBOLIZER_EXPORT, wxT("&Export to file"));
+  btnBox->Add(exp, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *copy = new wxButton(this, ID_SYMBOLIZER_COPY, wxT("&Copy"));
+  btnBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerInterpolateDialog::OnQuit);
+  Connect(ID_SYMBOLIZER_INSERT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerInterpolateDialog::OnInsert);
+  Connect(ID_SYMBOLIZER_EXPORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerInterpolateDialog::OnExport);
+  Connect(ID_SYMBOLIZER_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerInterpolateDialog::OnCopy);
+  Connect(ID_SYMBOLIZER_SHADED, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerInterpolateDialog::OnShadedChanged);
+  Connect(ID_SYMBOLIZER_ADD, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerInterpolateDialog::OnCmdAdd);
+  Connect(ID_SYMBOLIZER_REMOVE, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerInterpolateDialog::OnCmdRemove);
+  Connect(ID_SYMBOLIZER_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerInterpolateDialog::OnCmdColorPicker);
+  Connect(wxID_ANY, wxEVT_GRID_CELL_RIGHT_CLICK,
+          (wxObjectEventFunction) &
+          RasterSymbolizerInterpolateDialog::OnRightClick);
+  Connect(wxID_ANY, wxEVT_GRID_SELECT_CELL,
+          (wxObjectEventFunction) &
+          RasterSymbolizerInterpolateDialog::OnCellSelected);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerInterpolateDialog::OnCmdScaleChanged);
+}
+
+void RasterSymbolizerInterpolateDialog::
+OnCmdScaleChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Visibility Range selection changed
+//
+  wxRadioBox *scaleModeCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  switch (scaleModeCtrl->GetSelection())
+    {
+      case 0:
+        MinScale = false;
+        MaxScale = false;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 1:
+        MinScale = true;
+        MaxScale = false;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 2:
+        MinScale = false;
+        MaxScale = true;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+      case 3:
+        MinScale = true;
+        MaxScale = true;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+    };
+}
+
+void RasterSymbolizerInterpolateDialog::RefreshGrid()
+{
+//
+// refreshing the Grid
+//
+  int tot_rows = GridCtrl->GetNumberRows();
+  GridCtrl->DeleteRows(0, tot_rows);
+  int count = 0;
+  ColorMapEntry *pE = Map.GetFirst();
+  while (pE)
+    {
+      // counting how many lines are there
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl->AppendRows(count);
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pE = Map.GetFirst();
+  while (pE)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%1.6f", pE->GetValue());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 0, cell);
+      GridCtrl->SetCellAlignment(count, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 1, pE->GetColor());
+      wxColour color;
+      ColorMapEntry::GetWxColor(pE->GetColor(), color);
+      GridCtrl->SetCellBackgroundColour(count, 2, color);
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl->AutoSizeColumns();
+}
+
+void RasterSymbolizerInterpolateDialog::OnCellSelected(wxGridEvent & event)
+{
+//
+// cell selection changed
+//
+  CurrentRow = event.GetRow();
+  if (CurrentRow == 0)
+    return;
+  wxString value = GridCtrl->GetCellValue(CurrentRow, 0);
+  wxString color = GridCtrl->GetCellValue(CurrentRow, 1);
+  wxTextCtrl *valueCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_VALUE);
+  valueCtrl->SetValue(value);
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR);
+  colorCtrl->SetValue(color);
+}
+
+void RasterSymbolizerInterpolateDialog::OnRightClick(wxGridEvent & event)
+{
+//
+// right click on some cell [mouse action]
+//
+  wxMenu menu;
+  wxMenuItem *menuItem;
+  wxPoint pt = event.GetPosition();
+  CurrentRow = event.GetRow();
+  if (CurrentRow == 0)
+    return;
+  GridCtrl->SelectRow(CurrentRow);
+  wxString value = GridCtrl->GetCellValue(CurrentRow, 0);
+  double val;
+  value.ToDouble(&val);
+  CurrentValue = val;
+  menuItem = new wxMenuItem(&menu, ID_SYMBOLIZER_REMOVE, wxT("&Remove Entry"));
+  menu.Append(menuItem);
+  GridCtrl->PopupMenu(&menu, pt);
+}
+
+void RasterSymbolizerInterpolateDialog::
+OnCmdAdd(wxCommandEvent & WXUNUSED(event))
+{
+//
+// adding a new Map Entry
+//
+  wxTextCtrl *valueCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_VALUE);
+  wxString value = valueCtrl->GetValue();
+  double val;
+  if (value.ToDouble(&val) != true)
+    {
+      wxMessageBox(wxT
+                   ("VALUE isn't a valid decimal number !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR);
+  wxString color = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(color) != true)
+    {
+      wxMessageBox(wxT
+                   ("COLOR isn't a valid HexRGB color !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  Map.Add(val, color);
+  RefreshGrid();
+}
+
+void RasterSymbolizerInterpolateDialog::
+OnCmdRemove(wxCommandEvent & WXUNUSED(event))
+{
+//
+// removing a Map Entry
+//
+  Map.Remove(CurrentValue);
+  RefreshGrid();
+}
+
+void RasterSymbolizerInterpolateDialog::
+OnShadedChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// changed Shaded Relief (on/off): 
+//
+  wxCheckBox *shadedCtrl = (wxCheckBox *) FindWindow(ID_SYMBOLIZER_SHADED);
+  wxSpinCtrl *reliefCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_RELIEF);
+  if (shadedCtrl->IsChecked() == true)
+    {
+      reliefCtrl->SetRange(1, 200);
+      reliefCtrl->SetValue(25);
+      reliefCtrl->Enable(true);
+      ShadedRelief = true;
+  } else
+    {
+      reliefCtrl->SetRange(0, 0);
+      reliefCtrl->SetValue(0);
+      reliefCtrl->Enable(false);
+      ShadedRelief = false;
+    }
+}
+
+void RasterSymbolizerInterpolateDialog::
+OnCmdColorPicker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *pickerCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_PICKER_HEX);
+  wxColour clr = wxNullColour;
+  wxString str = pickerCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      pickerCtrl->SetValue(str);
+    }
+}
+
+bool RasterSymbolizerInterpolateDialog::RetrieveParams()
+{
+//
+// retrieving the RasterSymbolizer params 
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  Name = nameCtrl->GetValue();
+  if (Name.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the RasterSymbolizer NAME !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  Title = titleCtrl->GetValue();
+  if (Title.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer TITLE is warmly suggested\n\n");
+      msg += wxT("Do you really confirm leaving an empty (undefined) Title ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  Abstract = absCtrl->GetValue();
+  if (Abstract.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer ABSTRACT is warmly suggested\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an empty (undefined) Abstract ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_OPACITY);
+  Opacity = opacityCtrl->GetValue() / 100.0;
+  wxTextCtrl *fallbackCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FALLBACK);
+  Fallback = fallbackCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(Fallback) != true)
+    {
+      wxMessageBox(wxT
+                   ("FALLBACK isn't a valid HexRGB color !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  if (ShadedRelief == true)
+    {
+      wxSpinCtrl *reliefCtrl = (wxSpinCtrl *) FindWindow(ID_SYMBOLIZER_RELIEF);
+      ReliefFactor = reliefCtrl->GetValue();
+    }
+  if (MinScale == true)
+    {
+      wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+      wxString value = minCtrl->GetValue();
+      if (value.ToDouble(&MinScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MinScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MaxScale == true)
+    {
+      wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+      wxString value = maxCtrl->GetValue();
+      if (value.ToDouble(&MaxScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MaxScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MinScale == true && MaxScale == true)
+    {
+      if (MinScaleDenominator >= MaxScaleDenominator)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE is always expected to be greater than MIN_SCALE !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  return true;
+}
+
+char *RasterSymbolizerInterpolateDialog::DoCreateCoverageXML()
+{
+//
+// creating the SLD/SE (XML) code - CoverageStyle
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<CoverageStyle version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Rule>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (MinScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MinScaleDenominator>%1.2f</MinScaleDenominator>\r\n", prev,
+         MinScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MaxScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MaxScaleDenominator>%1.2f</MaxScaleDenominator>\r\n", prev,
+         MaxScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t<RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Fallback.ToUTF8()) + 1];
+  strcpy(str, Fallback.ToUTF8());
+  xml =
+    sqlite3_mprintf
+    ("%s\t<ColorMap>\r\n\t\t\t\t<Interpolate fallbackValue=\"%s\">\r\n", prev,
+     str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t\t\t\t<LookupValue>Rasterdata</LookupValue>\r\n",
+                    prev);
+  sqlite3_free(prev);
+  prev = xml;
+  ColorMapEntry *pE = Map.GetFirst();
+  while (pE != NULL)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t<InterpolationPoint>\r\n\t\t\t\t\t\t<Data>%1.6f</Data>\r\n",
+         prev, pE->GetValue());
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(pE->GetColor().ToUTF8()) + 1];
+      strcpy(str, pE->GetColor().ToUTF8());
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t\t\t<Value>%s</Value>\r\n\t\t\t\t\t</InterpolationPoint>\r\n",
+         prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      pE = pE->GetNext();
+    }
+  xml =
+    sqlite3_mprintf("%s\t\t\t\t</Interpolate>\r\n\t\t\t</ColorMap>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (ShadedRelief == true)
+    {
+      xml = sqlite3_mprintf("%s\t\t\t<ShadedRelief>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t<ReliefFactor>%1.2f</ReliefFactor>\r\n",
+                        prev, ReliefFactor);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t\t</ShadedRelief>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</Rule>\r\n</CoverageStyle>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+char *RasterSymbolizerInterpolateDialog::DoCreateSymbolizerXML()
+{
+//
+// creating the SLD/SE (XML) code - RasterSymbolizer
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<RasterSymbolizer version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/Symbolizer.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Fallback.ToUTF8()) + 1];
+  strcpy(str, Fallback.ToUTF8());
+  xml =
+    sqlite3_mprintf
+    ("%s\t<ColorMap>\r\n\t\t<Interpolate fallbackValue=\"%s\">\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t\t<LookupValue>Rasterdata</LookupValue>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  ColorMapEntry *pE = Map.GetFirst();
+  while (pE != NULL)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t<InterpolationPoint>\r\n\t\t\t\t<Data>%1.6f</Data>\r\n", prev,
+         pE->GetValue());
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(pE->GetColor().ToUTF8()) + 1];
+      strcpy(str, pE->GetColor().ToUTF8());
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<Value>%s</Value>\r\n\t\t\t</InterpolationPoint>\r\n", prev,
+         str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      pE = pE->GetNext();
+    }
+  xml = sqlite3_mprintf("%s\t\t</Interpolate>\r\n\t</ColorMap>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (ShadedRelief == true)
+    {
+      xml = sqlite3_mprintf("%s\t<ShadedRelief>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t<ReliefFactor>%1.2f</ReliefFactor>\r\n", prev,
+                        ReliefFactor);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t</ShadedRelief>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+void RasterSymbolizerInterpolateDialog::
+OnInsert(wxCommandEvent & WXUNUSED(event))
+{
+//
+// inserting the RasterSymbolizer into the DBMS
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  if (MainFrame->DoInsertRasterSymbolizer(xml) == true)
+    wxMessageBox(wxT
+                 ("SLD/SE RasterSymbolizer successfully registered into the DBMS"),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerInterpolateDialog::
+OnExport(wxCommandEvent & WXUNUSED(event))
+{
+//
+// exporting the RasterSymbolizer as an external file
+//
+  int ret;
+  wxString path;
+  wxString lastDir;
+  if (RetrieveParams() == false)
+    return;
+  wxFileDialog fileDialog(this,
+                          wxT("Exporting an SLD/SE RasterSymbolizer to a file"),
+                          wxT(""), Name + wxT(".xml"),
+                          wxT("XML Document|*.xml|All files (*.*)|*.*"),
+                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      wxFileName file(fileDialog.GetPath());
+      path = file.GetPath();
+      path += file.GetPathSeparator();
+      path += file.GetName();
+      lastDir = file.GetPath();
+      path = fileDialog.GetPath();
+      FILE *out = fopen(path.ToUTF8(), "wb");
+      if (out == NULL)
+        wxMessageBox(wxT("ERROR: unable to create:\n\n\"") + path + wxT("\""),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else
+        {
+          char *xml;
+          if (MinScale == true || MaxScale == true)
+            xml = DoCreateCoverageXML();
+          else
+            xml = DoCreateSymbolizerXML();
+          fwrite(xml, 1, strlen(xml), out);
+          sqlite3_free(xml);
+          fclose(out);
+          wxMessageBox(wxT
+                       ("SLD/SE RasterSymbolizer successfully saved into:\n\n\"")
+                       + path + wxT("\""), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerInterpolateDialog::OnCopy(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Copying the RasterSymbolizer into the Clipboard 
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  wxString XMLstring = wxString::FromUTF8(xml);
+  if (wxTheClipboard->Open())
+    {
+      wxTheClipboard->SetData(new wxTextDataObject(XMLstring));
+      wxTheClipboard->Close();
+    }
+}
+
+void RasterSymbolizerInterpolateDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool RasterSymbolizerMonochromeDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Color = wxT("#ff0000");
+  MinScale = false;
+  MaxScale = false;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("RasterSymbolizer: Recolored Monochrome")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void RasterSymbolizerMonochromeDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the RasterSymbolizer Name
+  wxBoxSizer *nameSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(nameSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *nameLabel = new wxStaticText(this, wxID_STATIC, wxT("&Name:"));
+  nameSizer->Add(nameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *nameCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_NAME, wxT(""),
+                                        wxDefaultPosition, wxSize(600, 22));
+  nameSizer->Add(nameCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the RasterSymbolizer Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the RasterSymbolizer Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_ABSTRACT, wxT(""),
+                   wxDefaultPosition, wxSize(600, 60),
+                   wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the RasterSymbolizer Opacity
+  wxBoxSizer *opacitySizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacitySizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *opacityLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Opacity:"));
+  opacitySizer->Add(opacityLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxSlider *opacityCtrl = new wxSlider(this, ID_SYMBOLIZER_OPACITY, 100, 0, 100,
+                                       wxDefaultPosition, wxSize(600, 45),
+                                       wxSL_HORIZONTAL | wxSL_LABELS);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// fifth row: the Remapped Color
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *remapBoxSizer = new wxBoxSizer(wxVERTICAL);
+  miscSizer->Add(remapBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *remapBox = new wxStaticBox(this, wxID_STATIC,
+                                          wxT("Black remapped Color"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *remapSizer = new wxStaticBoxSizer(remapBox, wxVERTICAL);
+  remapBoxSizer->Add(remapSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *colorSizer = new wxBoxSizer(wxHORIZONTAL);
+  remapSizer->Add(colorSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *colorCtrl = new wxTextCtrl(this, ID_SYMBOLIZER_COLOR, Color,
+                                         wxDefaultPosition, wxSize(100, 22));
+  colorSizer->Add(colorCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxTextCtrl *sampleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_PICKER_HEX, wxT("          "),
+                   wxDefaultPosition, wxSize(44, 22), wxTE_READONLY);
+  wxColour back = wxColour(255, 0, 0);
+  sampleCtrl->SetBackgroundColour(back);
+  colorSizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxBoxSizer *pickerSizer = new wxBoxSizer(wxHORIZONTAL);
+  remapSizer->Add(pickerSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxButton *pick =
+    new wxButton(this, ID_SYMBOLIZER_PICKER_BTN, wxT("&Pick a color"));
+  pickerSizer->Add(pick, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+// sixth row: optional Visibility Range
+  miscSizer->AddSpacer(75);
+  wxBoxSizer *visibilityBoxSizer = new wxBoxSizer(wxVERTICAL);
+  miscSizer->Add(visibilityBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *visibilityBox = new wxStaticBox(this, wxID_STATIC,
+                                               wxT("Visibility Range"),
+                                               wxDefaultPosition,
+                                               wxDefaultSize);
+  wxBoxSizer *visibilitySizer =
+    new wxStaticBoxSizer(visibilityBox, wxHORIZONTAL);
+  visibilityBoxSizer->Add(visibilitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL,
+                          5);
+  wxString range[4];
+  range[0] = wxT("&None");
+  range[1] = wxT("&Min");
+  range[2] = wxT("&Max");
+  range[3] = wxT("&Both");
+  wxRadioBox *rangeBox = new wxRadioBox(this, ID_SYMBOLIZER_MINMAX_SCALE,
+                                        wxT("&Range Type"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 4,
+                                        range, 2,
+                                        wxRA_SPECIFY_COLS);
+  visibilitySizer->Add(rangeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  rangeBox->SetSelection(0);
+  visibilitySizer->AddSpacer(20);
+  wxBoxSizer *scaleBoxSizer = new wxBoxSizer(wxVERTICAL);
+  visibilitySizer->Add(scaleBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *scaleMinSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMinSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *minScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Min Scale:"));
+  scaleMinSizer->Add(minScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *minScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MIN_SCALE, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  minScaleCtrl->Enable(false);
+  scaleMinSizer->Add(minScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *scaleMaxSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMaxSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *maxScaleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Max Scale:"));
+  scaleMaxSizer->Add(maxScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *maxScaleCtrl =
+    new wxTextCtrl(this, ID_SYMBOLIZER_MAX_SCALE, wxT("+Infinite"),
+                   wxDefaultPosition, wxSize(100, 22));
+  maxScaleCtrl->Enable(false);
+  scaleMaxSizer->Add(maxScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *insert =
+    new wxButton(this, ID_SYMBOLIZER_INSERT, wxT("&Insert into DBMS"));
+  btnBox->Add(insert, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *exp =
+    new wxButton(this, ID_SYMBOLIZER_EXPORT, wxT("&Export to file"));
+  btnBox->Add(exp, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *copy = new wxButton(this, ID_SYMBOLIZER_COPY, wxT("&Copy"));
+  btnBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerMonochromeDialog::OnQuit);
+  Connect(ID_SYMBOLIZER_INSERT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerMonochromeDialog::OnInsert);
+  Connect(ID_SYMBOLIZER_EXPORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerMonochromeDialog::OnExport);
+  Connect(ID_SYMBOLIZER_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSymbolizerMonochromeDialog::OnCopy);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerMonochromeDialog::OnCmdScaleChanged);
+  Connect(ID_SYMBOLIZER_COLOR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerMonochromeDialog::OnCmdColorChanged);
+  Connect(ID_SYMBOLIZER_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          RasterSymbolizerMonochromeDialog::OnCmdColorPicker);
+}
+
+void RasterSymbolizerMonochromeDialog::
+OnCmdColorChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// remapped color changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR);
+  wxTextCtrl *sampleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_PICKER_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void RasterSymbolizerMonochromeDialog::
+OnCmdColorPicker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+bool RasterSymbolizerMonochromeDialog::RetrieveParams()
+{
+//
+// retrieving the RasterSymbolizer params 
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  Name = nameCtrl->GetValue();
+  if (Name.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the RasterSymbolizer NAME !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  Title = titleCtrl->GetValue();
+  if (Title.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer TITLE is warmly suggested\n\n");
+      msg += wxT("Do you really confirm leaving an empty (undefined) Title ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  Abstract = absCtrl->GetValue();
+  if (Abstract.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some RasterSymbolizer ABSTRACT is warmly suggested\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an empty (undefined) Abstract ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_OPACITY);
+  Opacity = opacityCtrl->GetValue() / 100.0;
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR);
+  Color = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(Color) != true)
+    {
+      wxMessageBox(wxT
+                   ("REMAPPED_COLOR isn't a valid HexRGB color !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  if (MinScale == true)
+    {
+      wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+      wxString value = minCtrl->GetValue();
+      if (value.ToDouble(&MinScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MinScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MaxScale == true)
+    {
+      wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+      wxString value = maxCtrl->GetValue();
+      if (value.ToDouble(&MaxScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MaxScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MinScale == true && MaxScale == true)
+    {
+      if (MinScaleDenominator >= MaxScaleDenominator)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE is always expected to be greater than MIN_SCALE !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  return true;
+}
+
+void RasterSymbolizerMonochromeDialog::
+OnCmdScaleChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Visibility Range selection changed
+//
+  wxRadioBox *scaleModeCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  switch (scaleModeCtrl->GetSelection())
+    {
+      case 0:
+        MinScale = false;
+        MaxScale = false;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 1:
+        MinScale = true;
+        MaxScale = false;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 2:
+        MinScale = false;
+        MaxScale = true;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+      case 3:
+        MinScale = true;
+        MaxScale = true;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+    };
+}
+
+char *RasterSymbolizerMonochromeDialog::DoCreateCoverageXML()
+{
+//
+// creating the SLD/SE (XML) code - CoverageStyle
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<CoverageStyle version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Rule>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (MinScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MinScaleDenominator>%1.2f</MinScaleDenominator>\r\n", prev,
+         MinScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MaxScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MaxScaleDenominator>%1.2f</MaxScaleDenominator>\r\n", prev,
+         MaxScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t<RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t\t<ColorMap>\r\n\t\t\t\t<Categorize fallbackValue=\"#ffffff\">\r\n",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t\t\t\t<LookupValue>Rasterdata</LookupValue>\r\n",
+                    prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t\t\t<Value>#ffffff</Value>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Color.ToUTF8()) + 1];
+  strcpy(str, Color.ToUTF8());
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t\t\t\t<Threshold>1</Threshold>\r\n\t\t\t\t\t<Value>%s</Value>\r\n",
+     prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t\t\t</Categorize>\r\n\t\t\t</ColorMap>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</Rule>\r\n</CoverageStyle>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+char *RasterSymbolizerMonochromeDialog::DoCreateSymbolizerXML()
+{
+//
+// creating the SLD/SE (XML) code - RasterSymbolizer
+//
+  char *str;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<RasterSymbolizer version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/Symbolizer.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t<ColorMap>\r\n\t\t<Categorize fallbackValue=\"#ffffff\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%s\t\t\t<LookupValue>Rasterdata</LookupValue>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<Value>#ffffff</Value>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Color.ToUTF8()) + 1];
+  strcpy(str, Color.ToUTF8());
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t\t<Threshold>1</Threshold>\r\n\t\t\t<Value>%s</Value>\r\n", prev,
+     str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t</Categorize>\r\n\t</ColorMap>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s</RasterSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+void RasterSymbolizerMonochromeDialog::
+OnInsert(wxCommandEvent & WXUNUSED(event))
+{
+//
+// inserting the RasterSymbolizer into the DBMS
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  if (MainFrame->DoInsertRasterSymbolizer(xml) == true)
+    wxMessageBox(wxT
+                 ("SLD/SE RasterSymbolizer successfully registered into the DBMS"),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerMonochromeDialog::
+OnExport(wxCommandEvent & WXUNUSED(event))
+{
+//
+// exporting the RasterSymbolizer as an external file
+//
+  int ret;
+  wxString path;
+  wxString lastDir;
+  if (RetrieveParams() == false)
+    return;
+  wxFileDialog fileDialog(this,
+                          wxT("Exporting an SLD/SE RasterSymbolizer to a file"),
+                          wxT(""), Name + wxT(".xml"),
+                          wxT("XML Document|*.xml|All files (*.*)|*.*"),
+                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      wxFileName file(fileDialog.GetPath());
+      path = file.GetPath();
+      path += file.GetPathSeparator();
+      path += file.GetName();
+      lastDir = file.GetPath();
+      path = fileDialog.GetPath();
+      FILE *out = fopen(path.ToUTF8(), "wb");
+      if (out == NULL)
+        wxMessageBox(wxT("ERROR: unable to create:\n\n\"") + path + wxT("\""),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else
+        {
+          char *xml;
+          if (MinScale == true || MaxScale == true)
+            xml = DoCreateCoverageXML();
+          else
+            xml = DoCreateSymbolizerXML();
+          fwrite(xml, 1, strlen(xml), out);
+          sqlite3_free(xml);
+          fclose(out);
+          wxMessageBox(wxT
+                       ("SLD/SE RasterSymbolizer successfully saved into:\n\n\"")
+                       + path + wxT("\""), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+void RasterSymbolizerMonochromeDialog::OnCopy(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Copying the RasterSymbolizer into the Clipboard 
+//
+  if (RetrieveParams() == false)
+    return;
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateCoverageXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  wxString XMLstring = wxString::FromUTF8(xml);
+  if (wxTheClipboard->Open())
+    {
+      wxTheClipboard->SetData(new wxTextDataObject(XMLstring));
+      wxTheClipboard->Close();
+    }
+}
+
+void RasterSymbolizerMonochromeDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
diff --git a/ResultSetView.cpp b/ResultSetView.cpp
index 902f9a0..5d043ca 100644
--- a/ResultSetView.cpp
+++ b/ResultSetView.cpp
@@ -28,8 +28,6 @@
 #include "wx/clipbrd.h"
 #include "wx/filename.h"
 
-#include "gaiagraphics.h"
-
 #ifdef _WIN32
 #include <windows.h>
 #include <process.h>
@@ -63,6 +61,7 @@ wxPanel(parent, id, wxDefaultPosition, wxSize(440, 480), wxBORDER_SUNKEN)
   RsBlock = 500;                // the ResultSet block size
   RowIds = new sqlite3_int64[RsBlock];
   ReadOnly = true;
+  CoverageTiles = false;
   InsertRow = NULL;
   MainFrame = parent;
   BtnRsFirst =
@@ -117,6 +116,8 @@ wxPanel(parent, id, wxDefaultPosition, wxSize(440, 480), wxBORDER_SUNKEN)
           (wxObjectEventFunction) & MyResultSetView::OnCellChanged);
   Connect(Grid_Delete, wxEVT_COMMAND_MENU_SELECTED,
           (wxObjectEventFunction) & MyResultSetView::OnCmdDelete);
+  Connect(Grid_TilePreview, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyResultSetView::OnCmdTilePreview);
   Connect(Grid_Insert, wxEVT_COMMAND_MENU_SELECTED,
           (wxObjectEventFunction) & MyResultSetView::OnCmdInsert);
   Connect(Grid_Abort, wxEVT_COMMAND_MENU_SELECTED,
@@ -213,7 +214,7 @@ void MyResultSetView::EditTable(wxString & sql, int *primaryKeys, int *blobCols,
   ReadOnly = false;
   TableName = table;
   MainFrame->GetQueryView()->GetSqlCtrl()->SetValue(sql);
-  if (ExecuteSqlPre(sql, 0, ReadOnly) == false)
+  if (ExecuteSqlPre(sql, 0, ReadOnly, false, TileDataTable, true) == false)
     wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
                  MainFrame);
 }
@@ -338,15 +339,19 @@ int SqlProgressCallback(void *arg)
       return 0;
     }
 // updating query stats
-  fullscan =
-    sqlite3_stmt_status(params->GetStmt(), SQLITE_STMTSTATUS_FULLSCAN_STEP, 0);
-  sort = sqlite3_stmt_status(params->GetStmt(), SQLITE_STMTSTATUS_SORT, 0);
+  if (params->GetStmt() != NULL)
+    {
+      fullscan =
+        sqlite3_stmt_status(params->GetStmt(), SQLITE_STMTSTATUS_FULLSCAN_STEP,
+                            0);
+      sort = sqlite3_stmt_status(params->GetStmt(), SQLITE_STMTSTATUS_SORT, 0);
 #ifdef OMIT_SQLITE_STMTSTATUS_AUTOINXED
-  autoindex = -1;
+      autoindex = -1;
 #else
-  autoindex =
-    sqlite3_stmt_status(params->GetStmt(), SQLITE_STMTSTATUS_AUTOINDEX, 0);
+      autoindex =
+        sqlite3_stmt_status(params->GetStmt(), SQLITE_STMTSTATUS_AUTOINDEX, 0);
 #endif
+    }
   clock_end = clock();
   params->UpdateStats(fullscan, sort, autoindex, clock_end);
   if (params->GuiHasToBeUpdated(clock_end, 500) == true)
@@ -411,10 +416,7 @@ void *DoExecuteSqlThread(void *arg)
             }
           if ((i_row - params->GetFromRow()) >=
               params->GetMother()->GetRsBlock())
-            {
-              i_row++;
-              continue;
-            }
+            break;
           end_row = i_row;
           columns = sqlite3_column_count(params->GetStmt());
           MyRowVariant *rowVariant = params->GetList()->Add(columns);
@@ -463,7 +465,7 @@ void *DoExecuteSqlThread(void *arg)
           goto error;
         }
     }
-  sqlite3_finalize(params->GetStmt());
+  params->Finalize();
   params->SetEndRow(end_row);
   params->SetMaxRow(i_row);
   goto ok;
@@ -488,12 +490,119 @@ void MyResultSetView::AbortRequested()
     ThreadParams.Abort();
 }
 
-bool MyResultSetView::ExecuteSqlPre(wxString & sql, int from, bool read_only)
+const char *MyResultSetView::CleanSqlTail(const char *dirty)
+{
+// strips any leading white-space
+  const char *p = dirty;
+  while (p != '\0')
+    {
+      if (*p == ' ')
+        {
+          p++;
+          continue;
+        }
+      if (*p == '\t')
+        {
+          p++;
+          continue;
+        }
+      if (*p == '\n')
+        {
+          p++;
+          continue;
+        }
+      if (*p == '\r')
+        {
+          p++;
+          continue;
+        }
+      break;
+    }
+  return p;
+}
+
+void MyResultSetView::UpdateMaxRow(wxString & sql)
+{
+//
+// updating the max row value
+//
+  char *xSql = NULL;
+  char err_msg[2048];
+  sqlite3 *sqlite = MainFrame->GetSqlite();
+  sqlite3_stmt *stmt;
+  int i_row = 0;
+  int ret;
+
+  if (IsMaxAlreadySet)
+    return;
+  xSql = new char[(sql.Len() * 4) + 1];
+  strcpy(xSql, sql.ToUTF8());
+  const char *pSql = xSql;
+
+  ::wxBeginBusyCursor();
+  while (1)
+    {
+      const char *sql_tail;
+      ret = sqlite3_prepare_v2(sqlite, pSql, strlen(pSql), &stmt, &sql_tail);
+      if (ret != SQLITE_OK)
+        {
+          sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(sqlite));
+          SqlErrorMsg = wxString::FromUTF8(err_msg);
+          ::wxEndBusyCursor();
+          return;
+        }
+      pSql = CleanSqlTail(sql_tail);
+      if (strlen(pSql) == 0)
+        {
+          // this is the latest SQL statement in a (possibly) multiple
+          // request; enabling GUI processing of the resultset
+          break;
+        }
+      // silently consuming an intermediate SQL statement
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+        ;
+      else
+        {
+          sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(sqlite));
+          SqlErrorMsg = wxString::FromUTF8(err_msg);
+          ::wxEndBusyCursor();
+          sqlite3_finalize(stmt);
+          return;
+        }
+      sqlite3_finalize(stmt);
+    }
+  delete[]xSql;
+
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;                  // end of result set
+      if (ret == SQLITE_ROW)
+        i_row++;
+    }
+  sqlite3_finalize(stmt);
+  RsMaxRow = i_row;
+  ::wxEndBusyCursor();
+  IsMaxAlreadySet = true;
+}
+
+bool MyResultSetView::ExecuteSqlPre(wxString & sql, int from, bool read_only,
+                                    bool coverage_tile_data,
+                                    wxString & tile_data_table, bool reset)
 {
 //
 // executing some SQL statement
 //
   ReadOnly = read_only;
+  CoverageTiles = false;
+  if (coverage_tile_data == true)
+    {
+      ReadOnly = true;
+      CoverageTiles = true;
+      TileDataTable = tile_data_table;
+    }
   char *xSql = NULL;
   char err_msg[2048];
   int i_row;
@@ -514,7 +623,11 @@ bool MyResultSetView::ExecuteSqlPre(wxString & sql, int from, bool read_only)
   HideControls();
   RsBeginRow = 0;
   RsEndRow = 0;
-  RsMaxRow = 0;
+  if (reset == true)
+    {
+      RsMaxRow = 0;
+      IsMaxAlreadySet = false;
+    }
 #ifdef _WIN32
   HANDLE thread_handle;
   DWORD dwThreadId;
@@ -524,21 +637,50 @@ bool MyResultSetView::ExecuteSqlPre(wxString & sql, int from, bool read_only)
   for (i_row = 0; i_row < RsBlock; i_row++)
     RowIds[i_row] = -1;
   i_row = 0;
-  xSql = new char[65536];
+  xSql = new char[(sql.Len() * 4) + 1];
   strcpy(xSql, sql.ToUTF8());
+  const char *pSql = xSql;
 
   clock_start = clock();
-  int ret = sqlite3_prepare_v2(sqlite, xSql, strlen(xSql), &stmt, NULL);
-  delete[]xSql;
-  if (ret != SQLITE_OK)
+  ::wxBeginBusyCursor();
+  while (1)
     {
-      sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(sqlite));
-      SqlErrorMsg = wxString::FromUTF8(err_msg);
-      ::wxEndBusyCursor();
-      return false;
+      const char *sql_tail;
+      int ret =
+        sqlite3_prepare_v2(sqlite, pSql, strlen(pSql), &stmt, &sql_tail);
+      if (ret != SQLITE_OK)
+        {
+          sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(sqlite));
+          SqlErrorMsg = wxString::FromUTF8(err_msg);
+          ::wxEndBusyCursor();
+          delete[]xSql;
+          return false;
+        }
+      pSql = CleanSqlTail(sql_tail);
+      if (strlen(pSql) == 0)
+        {
+          // this is the latest SQL statement in a (possibly) multiple
+          // request; enabling GUI processing of the resultset
+          break;
+        }
+      // silently consuming an intermediate SQL statement
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+        ;
+      else
+        {
+          sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(sqlite));
+          SqlErrorMsg = wxString::FromUTF8(err_msg);
+          ::wxEndBusyCursor();
+          sqlite3_finalize(stmt);
+          delete[]xSql;
+          return false;
+        }
+      sqlite3_finalize(stmt);
     }
+  delete[]xSql;
   CreateStatsGrid();
-  ::wxBeginBusyCursor();
+  MainFrame->DisableAllTools();
 
   ThreadParams.Initialize(this, sql, stmt, from, sqlite, clock_start);
 #ifdef _WIN32
@@ -593,6 +735,7 @@ bool MyResultSetView::ExecuteSqlPost()
   wxString cellValue;
   wxString currentBlock;
   MyVariantList *list;
+  int decimal_precision = MainFrame->GetDecimalPrecision();
 
   MainFrame->GetQueryView()->DisableAbortButton();
   if (TableView)
@@ -637,7 +780,8 @@ bool MyResultSetView::ExecuteSqlPost()
     (double) (clock_end - ThreadParams.GetStart()) / (double) CLOCKS_PER_SEC;
   RsBeginRow = ThreadParams.GetFromRow();
   RsEndRow = ThreadParams.GetEndRow();
-  RsMaxRow = ThreadParams.GetMaxRow();
+  if (ThreadParams.GetMaxRow() > RsMaxRow)
+    RsMaxRow = ThreadParams.GetMaxRow();
   if (list->GetRows() == 0)
     {
       //
@@ -710,7 +854,13 @@ bool MyResultSetView::ExecuteSqlPost()
                                                     wxALIGN_TOP);
                         break;
                       case MY_DBL_VARIANT:
-                        sprintf(dummy, "%1.6f", value->GetDblValue());
+                        if (decimal_precision >= 0)
+                          {
+                            char fmt[64];
+                            sprintf(fmt, "%%1.%df", decimal_precision);
+                            sprintf(dummy, fmt, value->GetDblValue());
+                        } else
+                          sprintf(dummy, "%1.6f", value->GetDblValue());
                         cellValue = wxString::FromUTF8(dummy);
                         TableView->SetCellValue(i_row, i_col, cellValue);
                         if (ReadOnly == false)
@@ -736,6 +886,9 @@ bool MyResultSetView::ExecuteSqlPost()
                             case GAIA_GEOMETRY_BLOB:
                               blobType = wxT("GEOMETRY");
                               break;
+                            case GAIA_GPB_BLOB:
+                              blobType = wxT("GeoPackegeGEOMETRY");
+                              break;
                             case GAIA_XML_BLOB:
                               blobType = wxT("XmlBLOB");
                               break;
@@ -757,6 +910,12 @@ bool MyResultSetView::ExecuteSqlPost()
                             case GAIA_TIFF_BLOB:
                               blobType = wxT("TIFF image");
                               break;
+                            case GAIA_WEBP_BLOB:
+                              blobType = wxT("WEBP image");
+                              break;
+                            case GAIA_JP2_BLOB:
+                              blobType = wxT("JP2 image (Jpeg2000)");
+                              break;
                             case GAIA_PDF_BLOB:
                               blobType = wxT("PDF document");
                               break;
@@ -764,10 +923,12 @@ bool MyResultSetView::ExecuteSqlPost()
                               blobType = wxT("ZIP archive");
                               break;
                             default:
-                              if (gGraphIsRawImage
-                                  (value->GetBlob(),
-                                   value->GetBlobSize()) == GGRAPH_OK)
-                                blobType = wxT("RasterLite RAW image");
+                              // testing for an eventual Text Font
+                              int ret =
+                                rl2_is_valid_encoded_font(value->GetBlob(),
+                                                          value->GetBlobSize());
+                              if (ret == RL2_OK)
+                                blobType = wxT("TrueType Font");
                               break;
                           };
                         if (type == GAIA_XML_BLOB)
@@ -986,7 +1147,8 @@ void MyResultSetView::OnRsFirst(wxCommandEvent & WXUNUSED(event))
 // scrolling to the result set beginning
 //
   wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
-  if (ExecuteSqlPre(sql, 0, ReadOnly) == false)
+  if (ExecuteSqlPre(sql, 0, ReadOnly, CoverageTiles, TileDataTable, false) ==
+      false)
     wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
                  MainFrame);
 }
@@ -1000,7 +1162,8 @@ void MyResultSetView::OnRsPrevious(wxCommandEvent & WXUNUSED(event))
   int start = RsBeginRow - RsBlock;
   if (start < 0)
     start = 0;
-  if (ExecuteSqlPre(sql, start, ReadOnly) == false)
+  if (ExecuteSqlPre(sql, start, ReadOnly, CoverageTiles, TileDataTable, false)
+      == false)
     wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
                  MainFrame);
 }
@@ -1012,7 +1175,8 @@ void MyResultSetView::OnRsNext(wxCommandEvent & WXUNUSED(event))
 //
   wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
   int start = RsEndRow + 1;
-  if (ExecuteSqlPre(sql, start, ReadOnly) == false)
+  if (ExecuteSqlPre(sql, start, ReadOnly, CoverageTiles, TileDataTable, false)
+      == false)
     wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
                  MainFrame);
 }
@@ -1023,10 +1187,12 @@ void MyResultSetView::OnRsLast(wxCommandEvent & WXUNUSED(event))
 // scrolling to the result set ending
 //
   wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
+  UpdateMaxRow(sql);
   int start = RsMaxRow - RsBlock;
   if (start < 0)
     start = 0;
-  if (ExecuteSqlPre(sql, start, ReadOnly) == false)
+  if (ExecuteSqlPre(sql, start, ReadOnly, CoverageTiles, TileDataTable, false)
+      == false)
     wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
                  MainFrame);
 }
@@ -1038,7 +1204,8 @@ void MyResultSetView::OnRefresh(wxCommandEvent & WXUNUSED(event))
 //
   wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
   int start = RsBeginRow;
-  if (ExecuteSqlPre(sql, start, ReadOnly) == false)
+  if (ExecuteSqlPre(sql, start, ReadOnly, CoverageTiles, TileDataTable, false)
+      == false)
     wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
                  MainFrame);
 }
@@ -1048,6 +1215,7 @@ void MyResultSetView::OnThreadFinished(wxCommandEvent & WXUNUSED(event))
 //
 // the SQL thread signals termination
 //
+  MainFrame->EnableAllTools();
   if (ExecuteSqlPost() == false)
     wxMessageBox(wxT("An error occurred while showing the ResultSet"),
                  wxT("spatialite_gui"), wxOK | wxICON_ERROR, MainFrame);
@@ -1089,7 +1257,7 @@ void MyResultSetView::OnRightClick(wxGridEvent & event)
 //
   int blob_type;
   MyVariant *blobVar;
-  wxMenu *menu = new wxMenu();
+  wxMenu menu;
   wxMenuItem *menuItem;
   wxPoint pt = event.GetPosition();
   if (ReadOnly == false && event.GetRow() == TableView->GetNumberRows() - 1)
@@ -1098,18 +1266,30 @@ void MyResultSetView::OnRightClick(wxGridEvent & event)
       if (InsertPending == true)
         {
           menuItem =
-            new wxMenuItem(menu, Grid_Insert, wxT("&Confirm insertion"));
-          menu->Append(menuItem);
-          menuItem = new wxMenuItem(menu, Grid_Abort, wxT("&Abort insertion"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Grid_Insert, wxT("&Confirm insertion"));
+          menu.Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Grid_Abort, wxT("&Abort insertion"));
+          menu.Append(menuItem);
       } else
         {
-          menuItem = new wxMenuItem(menu, Grid_Insert, wxT("&Insert new row"));
-          menu->Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Grid_Insert, wxT("&Insert new row"));
+          menu.Append(menuItem);
         }
-      TableView->PopupMenu(menu, pt);
+      TableView->PopupMenu(&menu, pt);
       return;
     }
+  if (CoverageTiles == true)
+    {
+      // supporting Tile Preview
+      wxString value = TableView->GetCellValue(event.GetRow(), 0);
+      long tile_id;
+      value.ToLong(&tile_id);
+      CurrentTileId = tile_id;
+      menuItem =
+        new wxMenuItem(&menu, Grid_TilePreview, wxT("Raster &Tile Preview"));
+      menu.Append(menuItem);
+      goto done;
+    }
   CurrentEvtRow = event.GetRow();
   CurrentEvtColumn = event.GetCol();
   blobVar = TableBlobs->GetBlob(CurrentEvtRow, CurrentEvtColumn);
@@ -1121,46 +1301,46 @@ void MyResultSetView::OnRightClick(wxGridEvent & event)
           MyRowVariant *varRow = TableValues->GetRow(CurrentEvtRow);
           if (varRow->IsDeleted() == false)
             {
-              menuItem = new wxMenuItem(menu, Grid_Delete, wxT("&Delete row"));
-              menu->Append(menuItem);
+              menuItem = new wxMenuItem(&menu, Grid_Delete, wxT("&Delete row"));
+              menu.Append(menuItem);
               menuItem =
-                new wxMenuItem(menu, Grid_Insert, wxT("&Insert new row"));
-              menu->Append(menuItem);
-              menu->AppendSeparator();
+                new wxMenuItem(&menu, Grid_Insert, wxT("&Insert new row"));
+              menu.Append(menuItem);
+              menu.AppendSeparator();
             }
         }
-      menuItem = new wxMenuItem(menu, Grid_Blob, wxT("BLOB &explore"));
-      menu->Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Grid_Blob, wxT("BLOB &explore"));
+      menu.Append(menuItem);
       blob_type = gaiaGuessBlobType(blobVar->GetBlob(), blobVar->GetBlobSize());
       if (blob_type == GAIA_GEOMETRY_BLOB)
         ;
       else if (blob_type == GAIA_XML_BLOB)
         {
-          menu->AppendSeparator();
+          menu.AppendSeparator();
           menuItem =
-            new wxMenuItem(menu, Grid_XmlBlobIn, wxT("XmlBLOB &import"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Grid_XmlBlobIn, wxT("XmlBLOB &import"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Grid_XmlBlobOut,
+            new wxMenuItem(&menu, Grid_XmlBlobOut,
                            wxT("XmlBLOB &export (not indented)"));
-          menu->Append(menuItem);
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Grid_XmlBlobOutIndented,
+            new wxMenuItem(&menu, Grid_XmlBlobOutIndented,
                            wxT("XmlBLOB export (i&ndented)"));
-          menu->Append(menuItem);
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Grid_BlobNull, wxT("Set BLOB as &NULL"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Grid_BlobNull, wxT("Set BLOB as &NULL"));
+          menu.Append(menuItem);
       } else
         {
-          menu->AppendSeparator();
-          menuItem = new wxMenuItem(menu, Grid_BlobIn, wxT("BLOB &import"));
-          menu->Append(menuItem);
-          menuItem = new wxMenuItem(menu, Grid_BlobOut, wxT("BLOB &export"));
-          menu->Append(menuItem);
+          menu.AppendSeparator();
+          menuItem = new wxMenuItem(&menu, Grid_BlobIn, wxT("BLOB &import"));
+          menu.Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Grid_BlobOut, wxT("BLOB &export"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Grid_BlobNull, wxT("Set BLOB as &NULL"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Grid_BlobNull, wxT("Set BLOB as &NULL"));
+          menu.Append(menuItem);
         }
       CurrentBlob = blobVar;
   } else
@@ -1172,36 +1352,37 @@ void MyResultSetView::OnRightClick(wxGridEvent & event)
           MyRowVariant *varRow = TableValues->GetRow(CurrentEvtRow);
           if (varRow->IsDeleted() == false)
             {
-              menuItem = new wxMenuItem(menu, Grid_Delete, wxT("&Delete row"));
-              menu->Append(menuItem);
+              menuItem = new wxMenuItem(&menu, Grid_Delete, wxT("&Delete row"));
+              menu.Append(menuItem);
               menuItem =
-                new wxMenuItem(menu, Grid_Insert, wxT("&Insert new row"));
-              menu->Append(menuItem);
+                new wxMenuItem(&menu, Grid_Insert, wxT("&Insert new row"));
+              menu.Append(menuItem);
               if (IsBlobColumn(CurrentEvtColumn) == true)
                 {
-                  menu->AppendSeparator();
+                  menu.AppendSeparator();
                   menuItem =
-                    new wxMenuItem(menu, Grid_BlobIn, wxT("BLOB &import"));
-                  menu->Append(menuItem);
+                    new wxMenuItem(&menu, Grid_BlobIn, wxT("BLOB &import"));
+                  menu.Append(menuItem);
                 }
-              menu->AppendSeparator();
+              menu.AppendSeparator();
             }
         }
-      menuItem = new wxMenuItem(menu, Grid_Clear, wxT("&Clear selection"));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Grid_All, wxT("Select &all"));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Grid_Row, wxT("Select &row"));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Grid_Column, wxT("&Select column"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Grid_Copy, wxT("&Copy"));
-      menu->Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Grid_Clear, wxT("&Clear selection"));
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Grid_All, wxT("Select &all"));
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Grid_Row, wxT("Select &row"));
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Grid_Column, wxT("&Select column"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Grid_Copy, wxT("&Copy"));
+      menu.Append(menuItem);
       if (TableView->IsSelection() == false)
         menuItem->Enable(false);
     }
-  menu->AppendSeparator();
+done:
+  menu.AppendSeparator();
   wxMenu *exportMenu = new wxMenu();
   menuItem = new wxMenuItem(exportMenu, Grid_ExpTxtTab, wxT("as &Txt/Tab"));
   exportMenu->Append(menuItem);
@@ -1219,8 +1400,8 @@ void MyResultSetView::OnRightClick(wxGridEvent & event)
   exportMenu->Append(menuItem);
   menuItem = new wxMenuItem(exportMenu, Grid_ExpDbf, wxT("as &DBF archive"));
   exportMenu->Append(menuItem);
-  menu->AppendSubMenu(exportMenu, wxT("&Export ResultSet"));
-  TableView->PopupMenu(menu, pt);
+  menu.AppendSubMenu(exportMenu, wxT("&Export ResultSet"));
+  TableView->PopupMenu(&menu, pt);
 }
 
 void MyResultSetView::OnCellSelected(wxGridEvent & event)
@@ -1261,6 +1442,7 @@ void MyResultSetView::OnCellChanged(wxGridEvent & event)
   int row = event.GetRow();
   int column = event.GetCol();
   char xname[1024];
+  int decimal_precision = MainFrame->GetDecimalPrecision();
   value = TableView->GetCellValue(row, column);
   if (InsertPending == true)
     {
@@ -1295,7 +1477,14 @@ void MyResultSetView::OnCellChanged(wxGridEvent & event)
           newValue = wxString::FromUTF8(dummy);
       } else if (okDblValue == true)
         {
-          sprintf(dummy, "%1.6f", dbl_value);
+
+          if (decimal_precision >= 0)
+            {
+              char fmt[64];
+              sprintf(fmt, "%%1.%df", decimal_precision);
+              sprintf(dummy, fmt, dbl_value);
+          } else
+            sprintf(dummy, "%1.6f", dbl_value);
           newValue = wxString::FromUTF8(dummy);
       } else
         {
@@ -1337,7 +1526,14 @@ void MyResultSetView::OnCellChanged(wxGridEvent & event)
             }
           if (oldValue->GetType() == MY_DBL_VARIANT)
             {
-              sprintf(dummy, "%1.6f", oldValue->GetDblValue());
+
+              if (decimal_precision >= 0)
+                {
+                  char fmt[64];
+                  sprintf(fmt, "%%1.%df", decimal_precision);
+                  sprintf(dummy, fmt, oldValue->GetDblValue());
+              } else
+                sprintf(dummy, "%1.6f", oldValue->GetDblValue());
               value = wxString::FromUTF8(dummy);
             }
           if (oldValue->GetType() == MY_TXT_VARIANT)
@@ -1368,6 +1564,7 @@ void MyResultSetView::DoInsert(bool confirmed)
   char dummy[256];
   char *errMsg = NULL;
   char xname[1024];
+  int decimal_precision = MainFrame->GetDecimalPrecision();
   if (confirmed == false)
     {
       ret =
@@ -1403,7 +1600,14 @@ void MyResultSetView::DoInsert(bool confirmed)
         }
       if (var->GetType() == MY_DBL_VARIANT)
         {
-          sprintf(dummy, "%1.6f", var->GetDblValue());
+
+          if (decimal_precision >= 0)
+            {
+              char fmt[64];
+              sprintf(fmt, "%%1.%df", decimal_precision);
+              sprintf(dummy, fmt, var->GetDblValue());
+          } else
+            sprintf(dummy, "%1.6f", var->GetDblValue());
           value = wxString::FromUTF8(dummy);
         }
       if (var->GetType() == MY_TXT_VARIANT)
@@ -1622,6 +1826,21 @@ void MyResultSetView::OnCmdBlob(wxCommandEvent & WXUNUSED(event))
   dlg.ShowModal();
 }
 
+void MyResultSetView::OnCmdTilePreview(wxCommandEvent & WXUNUSED(event))
+{
+//
+// showing a Raster Tile Preview
+//
+  unsigned char *blob;
+  int blobSize;
+  if (MainFrame->GetTilePreview(TileDataTable, CurrentTileId, &blob, &blobSize)
+      != true)
+    return;
+  TilePreviewDialog dlg;
+  dlg.Create(MainFrame, TileDataTable, CurrentTileId, blobSize, blob);
+  dlg.ShowModal();
+}
+
 void MyResultSetView::OnCmdBlobIn(wxCommandEvent & WXUNUSED(event))
 {
 // importing an external file into a BLOB-value
@@ -1644,13 +1863,14 @@ void MyResultSetView::OnCmdBlobIn(wxCommandEvent & WXUNUSED(event))
   char xname[1024];
   fileList =
     wxT
-    ("BLOB Document (*.jpg;*.jpeg;*.png;*.gif;*.tif;*.pdf;*.zip)|*.jpg;*.jpeg;*.png;*.gif;*.tif;*.pdf;*.zip|");
+    ("BLOB Document (*.jpg;*.jpeg;*.jp2;*.png;*.gif;*.tif;*.pdf;*.zip)|*.jpg;*.jpeg;*.jp2;*.png;*.gif;*.tif;*.pdf;*.zip|");
   fileList +=
     wxT
-    ("Image (*.jpg;*.jpeg;*.png;*.gif;*.tif)|*.jpg;*.jpeg;*.png;*.gif;*.tif|");
+    ("Image (*.jpg;*.jpeg;*.jp2;*.png;*.gif;*.tif;*.webp)|*.jpg;*.jpeg;*.jp2;*.png;*.gif;*.tif;*.webp|");
   fileList +=
     wxT
-    ("JPEG Image (*.jpg;*.jpeg)|*.jpg;*.jpeg|PNG Image (*.png)|*.png|GIF Image (*.gif)|*.gif|TIFF Image (*.tif)|*.tif|");
+    ("JPEG Image (*.jpg;*.jpeg)|*.jpg;*.jpeg|Jpeg2000 Image (*.jp2)|*.jp2|PNG Image (*.png)|*.png|GIF Image (*.gif)|*.gif");
+  fileList += wxT("|TIFF Image (*.tif)|*.tif|WEBP Image (*.webp)|*.webp|");
   fileList +=
     wxT("PDF Document (*.pdf)|*.pdf|ZIP Archive|(*.zip)|All files (*.*)|*.*");
   wxFileDialog fileDialog(this, wxT("loading a BLOB value"),
@@ -1744,6 +1964,11 @@ void MyResultSetView::OnCmdBlobIn(wxCommandEvent & WXUNUSED(event))
               case GAIA_TIFF_BLOB:
                 blobValue += wxT("TIFF image");
                 break;
+              case GAIA_WEBP_BLOB:
+                blobValue += wxT("WEBP image");
+                break;
+              case GAIA_JP2_BLOB:
+                blobValue += wxT("JP2 image (Jpeg2000)");
               case GAIA_PDF_BLOB:
                 blobValue += wxT("PDF document");
                 break;
@@ -1751,7 +1976,12 @@ void MyResultSetView::OnCmdBlobIn(wxCommandEvent & WXUNUSED(event))
                 blobValue += wxT("ZIP archive");
                 break;
               default:
-                blobValue += wxT("UNKNOWN type");
+                // testing for an eventual Text Font
+                int ret = rl2_is_valid_encoded_font(buffer, rd);
+                if (ret == RL2_OK)
+                  blobValue += wxT("TrueType Font");
+                else
+                  blobValue += wxT("UNKNOWN type");
                 break;
             };
           TableView->SetCellValue(CurrentEvtRow, CurrentEvtColumn, blobValue);
@@ -1812,6 +2042,10 @@ void MyResultSetView::OnCmdBlobOut(wxCommandEvent & WXUNUSED(event))
         fileName = wxT("image.jpg");
         fileType = wxT("File JPEG (*.jpg;*.jpeg)|*.jpg");
         break;
+      case GAIA_JP2_BLOB:
+        fileName = wxT("image.jp2");
+        fileType = wxT("File Jpeg2000 (*.jp2)|*.jp2");
+        break;
       case GAIA_PNG_BLOB:
         fileName = wxT("image.png");
         fileType = wxT("File PNG (*.png)|*.png");
@@ -1857,6 +2091,9 @@ void MyResultSetView::OnCmdBlobOut(wxCommandEvent & WXUNUSED(event))
           case GAIA_EXIF_GPS_BLOB:
             path += wxT(".jpg");
             break;
+          case GAIA_JP2_BLOB:
+            path += wxT(".jp2");
+            break;
           case GAIA_PNG_BLOB:
             path += wxT(".png");
             break;
@@ -1987,7 +2224,7 @@ void MyResultSetView::OnCmdXmlBlobIn(wxCommandEvent & WXUNUSED(event))
         goto end;
 
 // attempting to parse (and possibly validate) the XML
-      gaiaXmlToBlob(MainFrame->GetInternalCache(), buffer, rd, compressed,
+      gaiaXmlToBlob(MainFrame->GetSpliteInternalCache(), buffer, rd, compressed,
                     schemaURI, &xml, &xml_size, NULL, NULL);
       if (xml == NULL)
         {
diff --git a/Shapefiles.cpp b/Shapefiles.cpp
index 9b02213..9f32f37 100644
--- a/Shapefiles.cpp
+++ b/Shapefiles.cpp
@@ -175,6 +175,29 @@ bool MyFrame::TableAlreadyExists(wxString & name)
   return already_exists;
 }
 
+bool MyFrame::CoverageAlreadyExists(wxString & name)
+{
+//
+// checks if a Raster Coverage of this name already exists 
+//
+  wxString table = name + wxT("_levels");
+  if (TableAlreadyExists(table) == true)
+    return true;
+  table = name + wxT("_sections");
+  if (TableAlreadyExists(table) == true)
+    return true;
+  table = name + wxT("_tile_data");
+  if (TableAlreadyExists(table) == true)
+    return true;
+  table = name + wxT("_tiles");
+  if (TableAlreadyExists(table) == true)
+    return true;
+  table = name + wxT("_section_levels");
+  if (TableAlreadyExists(table) == true)
+    return true;
+  return false;
+}
+
 bool MyFrame::SridNotExists(int srid)
 {
 //
@@ -338,16 +361,18 @@ void MyFrame::CleanSqlString(char *value)
   strcpy(value, new_value);
 }
 
-gaiaDbfFieldPtr MyFrame::GetDbfField(gaiaDbfListPtr list, char *name)
+gaiaDbfFieldPtr MyFrame::GetDbfField(gaiaDbfListPtr list, int index)
 {
 //
 // find a DBF attribute by name 
 //
+  int count = 0;
   gaiaDbfFieldPtr fld = list->First;
   while (fld)
     {
-      if (strcasecmp(fld->Name, name) == 0)
+      if (count == index)
         return fld;
+      count++;
       fld = fld->Next;
     }
   return NULL;
@@ -2268,6 +2293,14 @@ bool MyFrame::ExportHtmlColorSqlSyntax(FILE * out, wxString & sql, char *outCs)
           if (!gaiaConvertCharset(&pDummy, (const char *) "UTF-8", outCs))
             return false;
           fprintf(out, "<font class=\"funct\">%s</font>", dummy);
+      } else if (MyQueryView::IsSqlRasterFunction(token, next_c) == true)
+        {
+          // setting the SQL raster-function style
+          CleanHtml(dummy);
+          pDummy = dummy;
+          if (!gaiaConvertCharset(&pDummy, (const char *) "UTF-8", outCs))
+            return false;
+          fprintf(out, "<font class=\"funct\">%s</font>", dummy);
       } else
         {
           // setting normal style
@@ -2500,6 +2533,11 @@ void MyFrame::ExportResultSetAsDbf(wxString & path, wxString & sql,
               if (type == SQLITE_TEXT)
                 {
                   len = sqlite3_column_bytes(stmt, i);
+                  if (len > 254)
+                    {
+                      // DBF C type: max allowed length 
+                      len = 254;
+                    }
                   sql_type[i] = SQLITE_TEXT;
                   if (len > max_length[i])
                     max_length[i] = len;
@@ -2580,8 +2618,7 @@ void MyFrame::ExportResultSetAsDbf(wxString & path, wxString & sql,
           dbf_write = gaiaCloneDbfEntity(dbf->Dbf);
           for (i = 0; i < n_cols; i++)
             {
-              strcpy(dummy, sqlite3_column_name(stmt, i));
-              dbf_field = GetDbfField(dbf_write, dummy);
+              dbf_field = GetDbfField(dbf_write, i);
               if (!dbf_field)
                 continue;
               if (sqlite3_column_type(stmt, i) == SQLITE_NULL
@@ -2845,6 +2882,7 @@ void MyFrame::ExportResultSetAsShp(wxString & path, wxString & sql,
   int n_cols = 0;
   int offset = 0;
   int type;
+  int dbf_col;
   const void *blob_value;
   gaiaShapefilePtr shp = NULL;
   gaiaDbfListPtr dbf_list = NULL;
@@ -2914,6 +2952,11 @@ void MyFrame::ExportResultSetAsShp(wxString & path, wxString & sql,
               if (type == SQLITE_TEXT)
                 {
                   len = sqlite3_column_bytes(stmt, i);
+                  if (len > 254)
+                    {
+                      // DBF C: max allowed length
+                      len = 254;
+                    }
                   analyzer.UpdateText(i, len);
                 }
               if (type == SQLITE_INTEGER)
@@ -3061,6 +3104,7 @@ void MyFrame::ExportResultSetAsShp(wxString & path, wxString & sql,
           rows++;
           geom = NULL;
           dbf_write = gaiaCloneDbfEntity(dbf_list);
+          dbf_col = -1;
           for (i = 0; i < n_cols; i++)
             {
               if (strcasecmp
@@ -3080,9 +3124,10 @@ void MyFrame::ExportResultSetAsShp(wxString & path, wxString & sql,
                         gaiaFromSpatiaLiteBlobWkb((unsigned char *) blob_value,
                                                   len);
                     }
+                  continue;
                 }
-              strcpy(dummy, sqlite3_column_name(stmt, i));
-              dbf_field = GetDbfField(dbf_write, dummy);
+              dbf_col++;
+              dbf_field = GetDbfField(dbf_write, dbf_col);
               if (!dbf_field)
                 continue;
               if (sqlite3_column_type(stmt, i) == SQLITE_NULL)
diff --git a/Styles.cpp b/Styles.cpp
new file mode 100644
index 0000000..fe8dcf6
--- /dev/null
+++ b/Styles.cpp
@@ -0,0 +1,6742 @@
+/*
+/ Styles.cpp
+/ various dialog classes
+/
+/ version 1.8, 2015 March 13
+/
+/ Author: Sandro Furieri a-furieri at lqt.it
+/
+/ Copyright (C) 2015  Alessandro Furieri
+/
+/    This program is free software: you can redistribute it and/or modify
+/    it under the terms of the GNU General Public License as published by
+/    the Free Software Foundation, either version 3 of the License, or
+/    (at your option) any later version.
+/
+/    This program is distributed in the hope that it will be useful,
+/    but WITHOUT ANY WARRANTY; without even the implied warranty of
+/    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/    GNU General Public License for more details.
+/
+/    You should have received a copy of the GNU General Public License
+/    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+/
+*/
+
+#include "Classdef.h"
+
+#include "wx/spinctrl.h"
+#include "wx/filename.h"
+
+#include "rasterlite2/rasterlite2.h"
+#include "rasterlite2/rl2graphics.h"
+
+bool LoadRasterStyleDialog::Create(MyFrame * parent, wxArrayString & paths,
+                                   wxString & path)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Paths = paths;
+  Path = path;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Loading New SLD/SE Raster Style(s)")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void LoadRasterStyleDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: files to be imported
+  wxBoxSizer *fileSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(fileSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *fileLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("Import &File(s):"));
+  fileSizer->Add(fileLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *filesCtrl = new wxTextCtrl(this, wxID_ANY, Path,
+                                         wxDefaultPosition, wxSize(600, 60),
+                                         wxTE_MULTILINE | wxTE_READONLY);
+  fileSizer->Add(filesCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: progress report
+  wxBoxSizer *progrSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(progrSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *doneCtrl = new wxTextCtrl(this, ID_LOAD_STYLE_DONE, ListDone,
+                                        wxDefaultPosition, wxSize(650, 100),
+                                        wxTE_MULTILINE | wxTE_READONLY |
+                                        wxTE_RICH2);
+  progrSizer->Add(doneCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+
+// OK - CANCEL buttons
+  wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Import"));
+  okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Quit"));
+  okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *abort = new wxButton(this, ID_LOAD_ABORT, wxT("&Abort"));
+  abort->Enable(false);
+  okCancelBox->Add(abort, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadRasterStyleDialog::OnOk);
+  Connect(ID_LOAD_ABORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadRasterStyleDialog::OnCmdAbort);
+  Connect(ID_LOAD_RASTER_STYLE_START, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadRasterStyleDialog::OnRequestStart);
+  Connect(ID_LOAD_RASTER_STYLE_STOP, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadRasterStyleDialog::OnRequestStop);
+  Connect(ID_LOAD_RASTER_STYLE_SKIP, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadRasterStyleDialog::OnRequestSkip);
+  Connect(ID_LOAD_RASTER_STYLE_THREAD_FINISHED, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadRasterStyleDialog::OnThreadFinished);
+}
+
+void LoadRasterStyleDialog::OnCmdAbort(wxCommandEvent & WXUNUSED(event))
+{
+//
+// aborting the Raster Style(s) Import process
+//
+  if (Params.IsAbortPending() == true)
+    return;
+  Params.RequestAbort();
+  wxString report =
+    wxT("\nan ABORT request is now pending and will be accepted ASAP");
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_STYLE_DONE);
+  wxColour fore = wxColour(255, 255, 255);
+  wxColour back = wxColour(192, 0, 0);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(report);
+}
+
+void LoadRasterStyleDialog::OnRequestStart(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_STYLE_DONE);
+  wxColour fore = wxColour(255, 255, 255);
+  wxColour back = wxColour(0, 0, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(msg);
+  doneCtrl->MarkDirty();
+}
+
+void LoadRasterStyleDialog::OnRequestStop(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_STYLE_DONE);
+  ListDone += msg;
+  doneCtrl->Clear();
+  wxColour fore = wxColour(0, 0, 0);
+  wxColour back = wxColour(255, 255, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(ListDone);
+  doneCtrl->MarkDirty();
+}
+
+void LoadRasterStyleDialog::OnRequestSkip(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_STYLE_DONE);
+  ListDone += msg;
+  doneCtrl->Clear();
+  wxColour fore = wxColour(0, 0, 0);
+  wxColour back = wxColour(255, 0, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(ListDone);
+  doneCtrl->MarkDirty();
+}
+
+#ifdef _WIN32
+DWORD WINAPI DoExecuteRasterStylesLoad(void *arg)
+#else
+void *DoExecuteRasterStylesLoad(void *arg)
+#endif
+{
+//
+// threaded function: processing a Raster Style Import operation
+//
+  RasterStylesLoadParams *params = (RasterStylesLoadParams *) arg;
+  const char *sql;
+  int ret;
+  sqlite3_stmt *stmt = NULL;
+  int count = params->GetPathsCount();
+  int i;
+  clock_t clock_start;
+  clock_t clock_end;
+  double seconds;
+  char elapsed[64];
+  char ordinal[64];
+  wxString report;
+  wxString path;
+  void *blob;
+  int blob_size;
+  wxCommandEvent evt_start(wxEVT_COMMAND_BUTTON_CLICKED,
+                           ID_LOAD_RASTER_STYLE_START);
+  wxCommandEvent evt_stop(wxEVT_COMMAND_BUTTON_CLICKED,
+                          ID_LOAD_RASTER_STYLE_STOP);
+  wxCommandEvent evt_skip(wxEVT_COMMAND_BUTTON_CLICKED,
+                          ID_LOAD_RASTER_STYLE_SKIP);
+
+  sql = "SELECT SE_RegisterRasterStyle(?)";
+  ret =
+    sqlite3_prepare_v2(params->GetMainFrame()->GetSqlite(), sql, strlen(sql),
+                       &stmt, NULL);
+  if (ret != SQLITE_OK)
+    {
+      params->SetError();
+      goto error;
+    }
+
+  for (i = 0; i < count; i++)
+    {
+      // loading and verifying each Raster Style
+      if (params->IsAbortPending() == true)
+        {
+          report = wxT("STOP .... aborted by the user !!!!");
+          evt_start.SetString(report);
+          params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_start);
+          break;
+        }
+      path = params->GetPathByIndex(i);
+      params->SetCurrentPath(path);
+      report = wxT("Parsing and Validating: ") + path;
+      evt_start.SetString(report);
+      params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_start);
+      clock_start = clock();
+      if (params->GetMainFrame()->ValidateRasterStyle(path.ToUTF8(), &blob,
+                                                      &blob_size) == true)
+        {
+          if (params->GetDlg()->RegisterRasterStyle(stmt, blob, blob_size) !=
+              true)
+            {
+              params->SetError();
+              goto error;
+            }
+          clock_end = clock();
+          seconds =
+            (double) (clock_end - clock_start) / (double) CLOCKS_PER_SEC;
+          MyResultSetView::FormatElapsedTime(seconds, elapsed);
+          sprintf(ordinal, "done %d/%d: ", i + 1, count);
+          report =
+            wxString::FromUTF8(ordinal) + path + wxT("    [") +
+            wxString::FromUTF8(elapsed) + wxT("]\n");
+          evt_stop.SetString(report);
+          params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_stop);
+          params->Done();
+      } else
+        {
+          clock_end = clock();
+          seconds =
+            (double) (clock_end - clock_start) / (double) CLOCKS_PER_SEC;
+          MyResultSetView::FormatElapsedTime(seconds, elapsed);
+          sprintf(ordinal, "discarded %d/%d (not a valid Raster Style): ",
+                  i + 1, count);
+          report =
+            wxString::FromUTF8(ordinal) + path + wxT("    [") +
+            wxString::FromUTF8(elapsed) + wxT("]\n");
+          evt_skip.SetString(report);
+          params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_skip);
+        }
+    }
+  sqlite3_finalize(stmt);
+  goto end;
+
+error:
+  sqlite3_finalize(stmt);
+  report = wxT("FAILED: ") + path;
+  evt_stop.SetString(report);
+  params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_stop);
+  params->SetError();
+end:
+  wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED,
+                       ID_LOAD_RASTER_STYLE_THREAD_FINISHED);
+  params->GetDlg()->GetEventHandler()->AddPendingEvent(event);
+#ifdef _WIN32
+  return 0;
+#else
+  pthread_exit(NULL);
+#endif
+}
+
+void LoadRasterStyleDialog::OnThreadFinished(wxCommandEvent & WXUNUSED(event))
+{
+// resuming execution when the Import Raster thread quits
+  ::wxEndBusyCursor();
+  wxButton *quitBtn = (wxButton *) FindWindow(wxID_CANCEL);
+  wxButton *abortBtn = (wxButton *) FindWindow(ID_LOAD_ABORT);
+  quitBtn->Enable(true);
+  abortBtn->Enable(false);
+  sqlite3_exec(Params.GetMainFrame()->GetSqlite(), "COMMIT", NULL, NULL, NULL);
+  if (Params.GetError() == true)
+    {
+      char dummy[80];
+      sprintf(dummy, "%d Raster Styles have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy) +
+                   wxT("\n\nA fatal error occurred while loading:\n") +
+                   Params.GetCurrentPath(), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+  } else if (Params.IsAbortPending() == true)
+    {
+      char dummy[80];
+      sprintf(dummy, "%d Raster Styles have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy) +
+                   wxT("\n\nStopped by an Abort user request"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+  } else
+    {
+      char dummy[80];
+      sprintf(dummy, "%d Raster Styles have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy), wxT("spatialite_gui"),
+                   wxOK | wxICON_INFORMATION, this);
+    }
+}
+
+bool MyFrame::ValidateRasterStyle(const char *path, void **blob, int *blob_size)
+{
+//
+// attempting to parse and validate a Raster Style
+//
+  int ret;
+  sqlite3_stmt *stmt;
+  void *xblob = NULL;
+  int xblob_size;
+  int valid = 0;
+
+// Schema validation
+  char *sql = sqlite3_mprintf("SELECT XB_Create(XB_LoadXML(%Q), 1, 1)", path);
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    return false;
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_BLOB)
+            {
+              const void *xxblob = sqlite3_column_blob(stmt, 0);
+              xblob_size = sqlite3_column_bytes(stmt, 0);
+              xblob = malloc(xblob_size);
+              memcpy(xblob, xxblob, xblob_size);
+            }
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (xblob == NULL)
+    return false;
+
+// Checking if really is a Raster Style
+  stmt = NULL;
+  sql = sqlite3_mprintf("SELECT XB_IsSldSERasterStyle(?)");
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    goto invalid;
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_blob(stmt, 1, xblob, xblob_size, SQLITE_STATIC);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        goto invalid;
+    }
+  sqlite3_finalize(stmt);
+  stmt = NULL;
+  if (!valid)
+    goto invalid;
+  *blob = xblob;
+  *blob_size = xblob_size;
+  return true;
+
+invalid:
+  if (stmt != NULL)
+    sqlite3_finalize(stmt);
+  free(xblob);
+  *blob = NULL;
+  *blob_size = 0;
+  return false;
+}
+
+bool LoadRasterStyleDialog::RegisterRasterStyle(sqlite3_stmt * stmt, void *blob,
+                                                int blob_size)
+{
+//
+// attempting to register the new Raster Style
+//
+  int ret;
+  int valid = 0;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_blob(stmt, 1, blob, blob_size, free);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        return false;
+    }
+  if (valid)
+    return true;
+  return false;
+}
+
+void LoadRasterStyleDialog::DoRunLoad()
+{
+//
+// executing the Load Raster Style(s) process in a separate Thread
+//
+#ifdef _WIN32
+  HANDLE thread_handle;
+  DWORD dwThreadId;
+#else
+  pthread_t thread_id;
+#endif
+  Params.Initialize(MainFrame, this, Paths);
+#ifdef _WIN32
+  thread_handle =
+    CreateThread(NULL, 0, DoExecuteRasterStylesLoad, &Params, 0, &dwThreadId);
+  SetThreadPriority(thread_handle, THREAD_PRIORITY_IDLE);
+#else
+  int ok_prior = 0;
+  int policy;
+  int min_prio;
+  pthread_attr_t attr;
+  struct sched_param sp;
+  pthread_attr_init(&attr);
+  if (pthread_attr_setschedpolicy(&attr, SCHED_RR) == 0)
+    {
+      // attempting to set the lowest priority  
+      if (pthread_attr_getschedpolicy(&attr, &policy) == 0)
+        {
+          min_prio = sched_get_priority_min(policy);
+          sp.sched_priority = min_prio;
+          if (pthread_attr_setschedparam(&attr, &sp) == 0)
+            {
+              // ok, setting the lowest priority  
+              ok_prior = 1;
+              pthread_create(&thread_id, &attr, DoExecuteRasterStylesLoad,
+                             &Params);
+            }
+        }
+    }
+  if (!ok_prior)
+    {
+      // failure: using standard priority
+      pthread_create(&thread_id, NULL, DoExecuteRasterStylesLoad, &Params);
+    }
+#endif
+}
+
+void LoadRasterStyleDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxButton *loadBtn = (wxButton *) FindWindow(wxID_OK);
+  wxButton *quitBtn = (wxButton *) FindWindow(wxID_CANCEL);
+  wxButton *abortBtn = (wxButton *) FindWindow(ID_LOAD_ABORT);
+  loadBtn->Enable(false);
+  quitBtn->Enable(false);
+  abortBtn->Enable(true);
+  ::wxBeginBusyCursor();
+  char *errMsg = NULL;
+  int ret = sqlite3_exec(MainFrame->GetSqlite(), "BEGIN", NULL, NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") +
+                   wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      ::wxEndBusyCursor();
+      return;
+    }
+  DoRunLoad();
+}
+
+bool LoadVectorStyleDialog::Create(MyFrame * parent, wxArrayString & paths,
+                                   wxString & path)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Paths = paths;
+  Path = path;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Loading New SLD/SE Vector Style(s)")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void LoadVectorStyleDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: files to be imported
+  wxBoxSizer *fileSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(fileSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *fileLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("Import &File(s):"));
+  fileSizer->Add(fileLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *filesCtrl = new wxTextCtrl(this, wxID_ANY, Path,
+                                         wxDefaultPosition, wxSize(600, 60),
+                                         wxTE_MULTILINE | wxTE_READONLY);
+  fileSizer->Add(filesCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: progress report
+  wxBoxSizer *progrSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(progrSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *doneCtrl = new wxTextCtrl(this, ID_LOAD_STYLE_DONE, ListDone,
+                                        wxDefaultPosition, wxSize(650, 100),
+                                        wxTE_MULTILINE | wxTE_READONLY |
+                                        wxTE_RICH2);
+  progrSizer->Add(doneCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+
+// OK - CANCEL buttons
+  wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Import"));
+  okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Quit"));
+  okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *abort = new wxButton(this, ID_LOAD_ABORT, wxT("&Abort"));
+  abort->Enable(false);
+  okCancelBox->Add(abort, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadVectorStyleDialog::OnOk);
+  Connect(ID_LOAD_ABORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadVectorStyleDialog::OnCmdAbort);
+  Connect(ID_LOAD_VECTOR_STYLE_START, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadVectorStyleDialog::OnRequestStart);
+  Connect(ID_LOAD_VECTOR_STYLE_STOP, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadVectorStyleDialog::OnRequestStop);
+  Connect(ID_LOAD_VECTOR_STYLE_SKIP, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadVectorStyleDialog::OnRequestSkip);
+  Connect(ID_LOAD_VECTOR_STYLE_THREAD_FINISHED, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadVectorStyleDialog::OnThreadFinished);
+}
+
+void LoadVectorStyleDialog::OnCmdAbort(wxCommandEvent & WXUNUSED(event))
+{
+//
+// aborting the Vector Style(s) Import process
+//
+  if (Params.IsAbortPending() == true)
+    return;
+  Params.RequestAbort();
+  wxString report =
+    wxT("\nan ABORT request is now pending and will be accepted ASAP");
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_STYLE_DONE);
+  wxColour fore = wxColour(255, 255, 255);
+  wxColour back = wxColour(192, 0, 0);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(report);
+}
+
+void LoadVectorStyleDialog::OnRequestStart(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_STYLE_DONE);
+  wxColour fore = wxColour(255, 255, 255);
+  wxColour back = wxColour(0, 0, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(msg);
+  doneCtrl->MarkDirty();
+}
+
+void LoadVectorStyleDialog::OnRequestStop(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_STYLE_DONE);
+  ListDone += msg;
+  doneCtrl->Clear();
+  wxColour fore = wxColour(0, 0, 0);
+  wxColour back = wxColour(255, 255, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(ListDone);
+  doneCtrl->MarkDirty();
+}
+
+void LoadVectorStyleDialog::OnRequestSkip(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_STYLE_DONE);
+  ListDone += msg;
+  doneCtrl->Clear();
+  wxColour fore = wxColour(0, 0, 0);
+  wxColour back = wxColour(255, 0, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(ListDone);
+  doneCtrl->MarkDirty();
+}
+
+#ifdef _WIN32
+DWORD WINAPI DoExecuteVectorStylesLoad(void *arg)
+#else
+void *DoExecuteVectorStylesLoad(void *arg)
+#endif
+{
+//
+// threaded function: processing a Vector Style Import operation
+//
+  VectorStylesLoadParams *params = (VectorStylesLoadParams *) arg;
+  const char *sql;
+  int ret;
+  sqlite3_stmt *stmt = NULL;
+  int count = params->GetPathsCount();
+  int i;
+  clock_t clock_start;
+  clock_t clock_end;
+  double seconds;
+  char elapsed[64];
+  char ordinal[64];
+  wxString report;
+  wxString path;
+  void *blob;
+  int blob_size;
+  wxCommandEvent evt_start(wxEVT_COMMAND_BUTTON_CLICKED,
+                           ID_LOAD_VECTOR_STYLE_START);
+  wxCommandEvent evt_stop(wxEVT_COMMAND_BUTTON_CLICKED,
+                          ID_LOAD_VECTOR_STYLE_STOP);
+  wxCommandEvent evt_skip(wxEVT_COMMAND_BUTTON_CLICKED,
+                          ID_LOAD_VECTOR_STYLE_SKIP);
+
+  sql = "SELECT SE_RegisterVectorStyle(?)";
+  ret =
+    sqlite3_prepare_v2(params->GetMainFrame()->GetSqlite(), sql, strlen(sql),
+                       &stmt, NULL);
+  if (ret != SQLITE_OK)
+    {
+      params->SetError();
+      goto error;
+    }
+
+  for (i = 0; i < count; i++)
+    {
+      // loading and verifying each Vector Style
+      if (params->IsAbortPending() == true)
+        {
+          report = wxT("STOP .... aborted by the user !!!!");
+          evt_start.SetString(report);
+          params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_start);
+          break;
+        }
+      path = params->GetPathByIndex(i);
+      params->SetCurrentPath(path);
+      report = wxT("Parsing and Validating: ") + path;
+      evt_start.SetString(report);
+      params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_start);
+      clock_start = clock();
+      if (params->GetMainFrame()->ValidateVectorStyle(path.ToUTF8(), &blob,
+                                                      &blob_size) == true)
+        {
+          if (params->GetDlg()->RegisterVectorStyle(stmt, blob, blob_size) !=
+              true)
+            {
+              params->SetError();
+              goto error;
+            }
+          clock_end = clock();
+          seconds =
+            (double) (clock_end - clock_start) / (double) CLOCKS_PER_SEC;
+          MyResultSetView::FormatElapsedTime(seconds, elapsed);
+          sprintf(ordinal, "done %d/%d: ", i + 1, count);
+          report =
+            wxString::FromUTF8(ordinal) + path + wxT("    [") +
+            wxString::FromUTF8(elapsed) + wxT("]\n");
+          evt_stop.SetString(report);
+          params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_stop);
+          params->Done();
+      } else
+        {
+          clock_end = clock();
+          seconds =
+            (double) (clock_end - clock_start) / (double) CLOCKS_PER_SEC;
+          MyResultSetView::FormatElapsedTime(seconds, elapsed);
+          sprintf(ordinal, "discarded %d/%d (not a valid Vector Style): ",
+                  i + 1, count);
+          report =
+            wxString::FromUTF8(ordinal) + path + wxT("    [") +
+            wxString::FromUTF8(elapsed) + wxT("]\n");
+          evt_skip.SetString(report);
+          params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_skip);
+        }
+    }
+  sqlite3_finalize(stmt);
+  goto end;
+
+error:
+  sqlite3_finalize(stmt);
+  report = wxT("FAILED: ") + path;
+  evt_stop.SetString(report);
+  params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_stop);
+  params->SetError();
+end:
+  wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED,
+                       ID_LOAD_VECTOR_STYLE_THREAD_FINISHED);
+  params->GetDlg()->GetEventHandler()->AddPendingEvent(event);
+#ifdef _WIN32
+  return 0;
+#else
+  pthread_exit(NULL);
+#endif
+}
+
+void LoadVectorStyleDialog::OnThreadFinished(wxCommandEvent & WXUNUSED(event))
+{
+// resuming execution when the Import Vector thread quits
+  ::wxEndBusyCursor();
+  wxButton *quitBtn = (wxButton *) FindWindow(wxID_CANCEL);
+  wxButton *abortBtn = (wxButton *) FindWindow(ID_LOAD_ABORT);
+  quitBtn->Enable(true);
+  abortBtn->Enable(false);
+  sqlite3_exec(Params.GetMainFrame()->GetSqlite(), "COMMIT", NULL, NULL, NULL);
+  if (Params.GetError() == true)
+    {
+      char dummy[80];
+      sprintf(dummy, "%d Vector Styles have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy) +
+                   wxT("\n\nA fatal error occurred while loading:\n") +
+                   Params.GetCurrentPath(), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+  } else if (Params.IsAbortPending() == true)
+    {
+      char dummy[80];
+      sprintf(dummy, "%d Vector Styles have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy) +
+                   wxT("\n\nStopped by an Abort user request"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+  } else
+    {
+      char dummy[80];
+      sprintf(dummy, "%d Vector Styles have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy), wxT("spatialite_gui"),
+                   wxOK | wxICON_INFORMATION, this);
+    }
+}
+
+bool MyFrame::ValidateVectorStyle(const char *path, void **blob, int *blob_size)
+{
+//
+// attempting to parse and validate a Vector Style
+//
+  int ret;
+  sqlite3_stmt *stmt;
+  void *xblob = NULL;
+  int xblob_size;
+  int valid = 0;
+
+// Schema validation
+  char *sql = sqlite3_mprintf("SELECT XB_Create(XB_LoadXML(%Q), 1, 1)", path);
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    return false;
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_BLOB)
+            {
+              const void *xxblob = sqlite3_column_blob(stmt, 0);
+              xblob_size = sqlite3_column_bytes(stmt, 0);
+              xblob = malloc(xblob_size);
+              memcpy(xblob, xxblob, xblob_size);
+            }
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (xblob == NULL)
+    return false;
+
+// Checking if really is a Vector Style
+  stmt = NULL;
+  sql = sqlite3_mprintf("SELECT XB_IsSldSEVectorStyle(?)");
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    goto invalid;
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_blob(stmt, 1, xblob, xblob_size, SQLITE_STATIC);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        goto invalid;
+    }
+  sqlite3_finalize(stmt);
+  stmt = NULL;
+  if (!valid)
+    goto invalid;
+  *blob = xblob;
+  *blob_size = xblob_size;
+  return true;
+
+invalid:
+  if (stmt != NULL)
+    sqlite3_finalize(stmt);
+  free(xblob);
+  *blob = NULL;
+  *blob_size = 0;
+  return false;
+}
+
+bool LoadVectorStyleDialog::RegisterVectorStyle(sqlite3_stmt * stmt, void *blob,
+                                                int blob_size)
+{
+//
+// attempting to register the new Vector Style
+//
+  int ret;
+  int valid = 0;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_blob(stmt, 1, blob, blob_size, free);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        return false;
+    }
+  if (valid)
+    return true;
+  return false;
+}
+
+void LoadVectorStyleDialog::DoRunLoad()
+{
+//
+// executing the Load Vector Style(s) process in a separate Thread
+//
+#ifdef _WIN32
+  HANDLE thread_handle;
+  DWORD dwThreadId;
+#else
+  pthread_t thread_id;
+#endif
+  Params.Initialize(MainFrame, this, Paths);
+#ifdef _WIN32
+  thread_handle =
+    CreateThread(NULL, 0, DoExecuteVectorStylesLoad, &Params, 0, &dwThreadId);
+  SetThreadPriority(thread_handle, THREAD_PRIORITY_IDLE);
+#else
+  int ok_prior = 0;
+  int policy;
+  int min_prio;
+  pthread_attr_t attr;
+  struct sched_param sp;
+  pthread_attr_init(&attr);
+  if (pthread_attr_setschedpolicy(&attr, SCHED_RR) == 0)
+    {
+      // attempting to set the lowest priority  
+      if (pthread_attr_getschedpolicy(&attr, &policy) == 0)
+        {
+          min_prio = sched_get_priority_min(policy);
+          sp.sched_priority = min_prio;
+          if (pthread_attr_setschedparam(&attr, &sp) == 0)
+            {
+              // ok, setting the lowest priority  
+              ok_prior = 1;
+              pthread_create(&thread_id, &attr, DoExecuteVectorStylesLoad,
+                             &Params);
+            }
+        }
+    }
+  if (!ok_prior)
+    {
+      // failure: using standard priority
+      pthread_create(&thread_id, NULL, DoExecuteVectorStylesLoad, &Params);
+    }
+#endif
+}
+
+void LoadVectorStyleDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxButton *loadBtn = (wxButton *) FindWindow(wxID_OK);
+  wxButton *quitBtn = (wxButton *) FindWindow(wxID_CANCEL);
+  wxButton *abortBtn = (wxButton *) FindWindow(ID_LOAD_ABORT);
+  loadBtn->Enable(false);
+  quitBtn->Enable(false);
+  abortBtn->Enable(true);
+  ::wxBeginBusyCursor();
+  char *errMsg = NULL;
+  int ret = sqlite3_exec(MainFrame->GetSqlite(), "BEGIN", NULL, NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") +
+                   wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      ::wxEndBusyCursor();
+      return;
+    }
+  DoRunLoad();
+}
+
+bool RasterCoverageStylesDialog::Create(MyFrame * parent, wxString & coverage)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  int pos = coverage.Find(wxT(" [SRID="));
+  if (pos != wxNOT_FOUND)
+    CoverageName = coverage.Left(pos);
+  else
+    CoverageName = coverage;
+  List = MainFrame->FindRasterCoverageStyles(CoverageName);
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Raster Coverage supported SLD/SE Styles")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void RasterCoverageStylesDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Coverage Name
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_CENTRE_VERTICAL | wxALL, 0);
+  wxStaticText *cvgLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Coverage Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, wxID_ANY, CoverageName,
+                                       wxDefaultPosition, wxSize(350, 22),
+                                       wxTE_READONLY);
+  cvgCtrl->Enable(false);
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered SLD/SE Styles"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_SLD_SE_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  RasterCoverageStyle *pS = List->GetFirst();
+  while (pS)
+    {
+      // counting how many lines are there
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 6, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Style ID"));
+  GridCtrl->SetColLabelValue(1, wxT("Name"));
+  GridCtrl->SetColLabelValue(2, wxT("Title"));
+  GridCtrl->SetColLabelValue(3, wxT("Abstract"));
+  GridCtrl->SetColLabelValue(4, wxT("Schema Validated"));
+  GridCtrl->SetColLabelValue(5, wxT("Schema URI"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pS = List->GetFirst();
+  while (pS)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%d", count + 1);
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetRowLabelValue(count, cell);
+      sprintf(dummy, "%d", pS->GetStyleID());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 0, cell);
+      GridCtrl->SetCellAlignment(count, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 1, pS->GetName());
+      GridCtrl->SetCellValue(count, 2, pS->GetTitle());
+      GridCtrl->SetCellValue(count, 3, pS->GetAbstract());
+      GridCtrl->SetCellValue(count, 4, pS->GetSchemaValidated());
+      GridCtrl->SetCellValue(count, 5, pS->GetSchemaURI());
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *quit = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(quit, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *addNew = new wxButton(this, ID_SLD_SE_ADD, wxT("&Add Style(s)"));
+  btnBox->Add(addNew, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterCoverageStylesDialog::OnQuit);
+  Connect(ID_SLD_SE_ADD, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterCoverageStylesDialog::OnAddStyle);
+  Connect(ID_SLD_SE_REMOVE, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) &
+          RasterCoverageStylesDialog::OnCmdRemoveStyle);
+  Connect(wxID_ANY, wxEVT_GRID_CELL_RIGHT_CLICK,
+          (wxObjectEventFunction) & RasterCoverageStylesDialog::OnRightClick);
+}
+
+void RasterCoverageStylesDialog::OnRightClick(wxGridEvent & event)
+{
+//
+// right click on some cell [mouse action]
+//
+  wxMenu menu;
+  wxMenuItem *menuItem;
+  wxPoint pt = event.GetPosition();
+  CurrentRow = event.GetRow();
+  GridCtrl->SelectRow(CurrentRow);
+  wxString id = GridCtrl->GetCellValue(CurrentRow, 0);
+  long style_id;
+  id.ToLong(&style_id);
+  CurrentStyleID = style_id;
+  menuItem = new wxMenuItem(&menu, ID_SLD_SE_REMOVE, wxT("&Remove"));
+  menu.Append(menuItem);
+  GridCtrl->PopupMenu(&menu, pt);
+}
+
+void RasterCoverageStylesDialog::
+OnCmdRemoveStyle(wxCommandEvent & WXUNUSED(event))
+{
+//
+// deleting a Style [mouse action]
+//
+  sqlite3_stmt *stmt = NULL;
+  const char *sql = "SELECT SE_UnRegisterRasterStyledLayer(?, ?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_int(stmt, 2, CurrentStyleID);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+    GridCtrl->DeleteRows(CurrentRow, 1);
+  sqlite3_finalize(stmt);
+}
+
+void RasterCoverageStylesDialog::
+DoRegistetRasterCoverageStyles(ListRasterStylesDialog * dlg)
+{
+//
+// attempting to register the Raster Coverage Style(s)
+//
+  sqlite3_stmt *stmt = NULL;
+  const char *sql = "SELECT SE_RegisterRasterStyledLayer(?, ?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return;
+
+  int max = dlg->GetSelectedCount();
+  for (int i = 0; i < max; i++)
+    {
+      int style_id = dlg->GetSelectedStyleId(i);
+      if (style_id >= 0)
+        {
+          sqlite3_reset(stmt);
+          sqlite3_clear_bindings(stmt);
+          sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1,
+                            SQLITE_TRANSIENT);
+          sqlite3_bind_int(stmt, 2, style_id);
+          ret = sqlite3_step(stmt);
+          if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+            ;
+          else
+            {
+              sqlite3_finalize(stmt);
+              return;
+            }
+        }
+    }
+  sqlite3_finalize(stmt);
+}
+
+void RasterCoverageStylesDialog::OnAddStyle(wxCommandEvent & WXUNUSED(event))
+{
+//
+// adding a new Style [button action]
+//
+  ListRasterStylesDialog dlg;
+  dlg.Create(MainFrame);
+  if (dlg.ShowModal() == wxID_OK)
+    {
+      // attempting to register the new styles
+      DoRegistetRasterCoverageStyles(&dlg);
+
+      // updating the Grid
+      int tot_rows = GridCtrl->GetNumberRows();
+      GridCtrl->DeleteRows(0, tot_rows);
+      if (List != NULL)
+        delete List;
+      List = MainFrame->FindRasterCoverageStyles(CoverageName);
+      int count = 0;
+      RasterCoverageStyle *pS = List->GetFirst();
+      while (pS)
+        {
+          // counting how many lines are there
+          count++;
+          pS = pS->GetNext();
+        }
+      GridCtrl->AppendRows(count);
+      count = 0;
+      char dummy[1024];
+      wxString cell;
+      pS = List->GetFirst();
+      while (pS)
+        {
+          // feeding grid rows
+          sprintf(dummy, "%d", count + 1);
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetRowLabelValue(count, cell);
+          sprintf(dummy, "%d", pS->GetStyleID());
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetCellValue(count, 0, cell);
+          GridCtrl->SetCellAlignment(count, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+          GridCtrl->SetCellValue(count, 1, pS->GetName());
+          GridCtrl->SetCellValue(count, 2, pS->GetTitle());
+          GridCtrl->SetCellValue(count, 3, pS->GetAbstract());
+          GridCtrl->SetCellValue(count, 4, pS->GetSchemaValidated());
+          GridCtrl->SetCellValue(count, 5, pS->GetSchemaURI());
+          count++;
+          pS = pS->GetNext();
+        }
+      GridCtrl->AutoSizeColumns();
+    }
+}
+
+void RasterCoverageStylesDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool ListRasterStylesDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  List = MainFrame->FindRasterStyles();
+  if (wxDialog::Create(parent, wxID_ANY, wxT("Registered SLD/SE Raster Styles"))
+      == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void ListRasterStylesDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered SLD/SE Styles"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_SLD_SE_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  RasterCoverageStyle *pS = List->GetFirst();
+  while (pS)
+    {
+      // counting how many lines are there
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 6, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Style ID"));
+  GridCtrl->SetColLabelValue(1, wxT("Name"));
+  GridCtrl->SetColLabelValue(2, wxT("Title"));
+  GridCtrl->SetColLabelValue(3, wxT("Abstract"));
+  GridCtrl->SetColLabelValue(4, wxT("Schema Validated"));
+  GridCtrl->SetColLabelValue(5, wxT("Schema URI"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pS = List->GetFirst();
+  while (pS)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%d", count + 1);
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetRowLabelValue(count, cell);
+      sprintf(dummy, "%d", pS->GetStyleID());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 0, cell);
+      GridCtrl->SetCellAlignment(count, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 1, pS->GetName());
+      GridCtrl->SetCellValue(count, 2, pS->GetTitle());
+      GridCtrl->SetCellValue(count, 3, pS->GetAbstract());
+      GridCtrl->SetCellValue(count, 4, pS->GetSchemaValidated());
+      GridCtrl->SetCellValue(count, 5, pS->GetSchemaURI());
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Ok"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel"));
+  btnBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & ListRasterStylesDialog::OnOk);
+}
+
+int ListRasterStylesDialog::GetSelectedCount()
+{
+//
+// computing how many selected Style there are
+//
+  int count = 0;
+  RasterCoverageStyle *pS = List->GetFirst();
+  while (pS != NULL)
+    {
+      if (pS->IsSelected() == true)
+        count++;
+      pS = pS->GetNext();
+    }
+  return count;
+}
+
+int ListRasterStylesDialog::GetSelectedStyleId(int idx)
+{
+//
+// returning the Nth selected StyleID
+//
+  int count = 0;
+  RasterCoverageStyle *pS = List->GetFirst();
+  while (pS != NULL)
+    {
+      if (pS->IsSelected() == true)
+        {
+          if (count == idx)
+            return pS->GetStyleID();
+          count++;
+        }
+      pS = pS->GetNext();
+    }
+  return -1;
+}
+
+void ListRasterStylesDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  for (int i = 0; i < GridCtrl->GetNumberRows(); i++)
+    {
+      if (GridCtrl->IsInSelection(i, 0) == true)
+        {
+          wxString cell_id = GridCtrl->GetCellValue(i, 0);
+          long style_id;
+          if (cell_id.ToLong(&style_id) == true)
+            List->MarkSelected(style_id);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+RasterCoverageStyle::RasterCoverageStyle(int style_id, wxString & name,
+                                         wxString & title, wxString & abstract,
+                                         wxString & validated,
+                                         wxString & schema_uri)
+{
+// constructor
+  StyleID = style_id;
+  Name = name;
+  Title = title;
+  Abstract = abstract;
+  SchemaValidated = validated;
+  SchemaURI = schema_uri;
+  Selected = false;
+  Next = NULL;
+}
+
+RasterCoverageStylesList::RasterCoverageStylesList()
+{
+// constructor
+  First = NULL;
+  Last = NULL;
+}
+
+RasterCoverageStylesList::~RasterCoverageStylesList()
+{
+// destructor
+  RasterCoverageStyle *pS;
+  RasterCoverageStyle *pSn;
+  pS = First;
+  while (pS != NULL)
+    {
+      pSn = pS->GetNext();
+      delete pS;
+      pS = pSn;
+    }
+}
+
+void RasterCoverageStylesList::Add(int style_id, wxString & name,
+                                   wxString & title, wxString & abstract,
+                                   wxString & validated, wxString & schema_uri)
+{
+// inserting a new Style
+  RasterCoverageStyle *pS =
+    new RasterCoverageStyle(style_id, name, title, abstract, validated,
+                            schema_uri);
+  if (First == NULL)
+    First = pS;
+  if (Last != NULL)
+    Last->SetNext(pS);
+  Last = pS;
+}
+
+void RasterCoverageStylesList::MarkSelected(int styleId)
+{
+// marking a Selected Style
+  RasterCoverageStyle *pS;
+  pS = First;
+  while (pS != NULL)
+    {
+      if (pS->GetStyleID() == styleId)
+        {
+          pS->MarkSelected();
+          break;
+        }
+      pS = pS->GetNext();
+    }
+}
+
+RasterCoverageStylesList *MyFrame::FindRasterCoverageStyles(wxString & coverage)
+{
+// will retrieve all SLD/SE Styles for the given Coverage
+  RasterCoverageStylesList *list = new RasterCoverageStylesList();
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  char *value;
+  wxString sql;
+
+  sql =
+    wxT
+    ("SELECT style_id, name, title, abstract, schema_validated, schema_uri ");
+  sql +=
+    wxT("FROM SE_raster_styled_layers_view WHERE coverage_name = '") + coverage;
+  sql += wxT("' ORDER BY style_id");
+  int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
+                              &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return list;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          value = results[(i * columns) + 0];
+          int style_id = atoi(value);
+          value = results[(i * columns) + 1];
+          wxString name = wxString::FromUTF8(value);
+          value = results[(i * columns) + 2];
+          wxString title = wxString::FromUTF8(value);
+          value = results[(i * columns) + 3];
+          wxString abstract = wxString::FromUTF8(value);
+          value = results[(i * columns) + 1];
+          wxString validated = wxT("Yes");
+          if (atoi(value) == 0)
+            validated = wxT("No");
+          value = results[(i * columns) + 5];
+          wxString schema_uri = wxString::FromUTF8(value);
+          list->Add(style_id, name, title, abstract, validated, schema_uri);
+        }
+    }
+  sqlite3_free_table(results);
+  return list;
+}
+
+RasterCoverageStylesList *MyFrame::FindRasterStyles()
+{
+// will retrieve all registered SLD/SE Raster Styles
+  RasterCoverageStylesList *list = new RasterCoverageStylesList();
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  char *value;
+  const char *sql;
+
+  sql =
+    "SELECT style_id, style_name, XB_GetTitle(style), XB_GetAbstract(style), "
+    "XB_IsSchemaValidated(style), XB_GetSchemaURI(style) "
+    "FROM SE_raster_styles ORDER BY style_name";
+  int ret = sqlite3_get_table(SqliteHandle, sql, &results,
+                              &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return list;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          value = results[(i * columns) + 0];
+          int style_id = atoi(value);
+          value = results[(i * columns) + 1];
+          wxString name = wxString::FromUTF8(value);
+          value = results[(i * columns) + 2];
+          wxString title = wxString::FromUTF8(value);
+          value = results[(i * columns) + 3];
+          wxString abstract = wxString::FromUTF8(value);
+          value = results[(i * columns) + 1];
+          wxString validated = wxT("Yes");
+          if (atoi(value) == 0)
+            validated = wxT("No");
+          value = results[(i * columns) + 5];
+          wxString schema_uri = wxString::FromUTF8(value);
+          list->Add(style_id, name, title, abstract, validated, schema_uri);
+        }
+    }
+  sqlite3_free_table(results);
+  return list;
+}
+
+CandidateVectorCoveragesList::~CandidateVectorCoveragesList()
+{
+// destructor
+  CandidateVectorCoverage *pC;
+  CandidateVectorCoverage *pCn;
+  pC = First;
+  while (pC != NULL)
+    {
+      pCn = pC->GetNext();
+      delete pC;
+      pC = pCn;
+    }
+}
+
+void CandidateVectorCoveragesList::Add(wxString & table_name,
+                                       wxString & geometry, int srid,
+                                       wxString & type)
+{
+// inserting a new candidate Vector Coverage
+  CandidateVectorCoverage *pC =
+    new CandidateVectorCoverage(table_name, geometry, srid, type);
+  if (First == NULL)
+    First = pC;
+  if (Last != NULL)
+    Last->SetNext(pC);
+  Last = pC;
+}
+
+void CandidateVectorCoveragesList::MarkVectorCoverage(wxString & table,
+                                                      wxString & geometry)
+{
+// marking an already registered Vector Coverage
+  CandidateVectorCoverage *pC;
+  pC = First;
+  while (pC != NULL)
+    {
+      if (pC->GetTableName().CmpNoCase(table) == 0
+          && pC->GetGeometryColumn().CmpNoCase(geometry) == 0)
+        {
+          pC->MarkVectorCoverage();
+          break;
+        }
+      pC = pC->GetNext();
+    }
+}
+
+void CandidateVectorCoveragesList::MarkRasterCoverage(wxString & table,
+                                                      wxString & geometry)
+{
+// marking a some table related to an already registered Raster Coverage
+  CandidateVectorCoverage *pC;
+  pC = First;
+  while (pC != NULL)
+    {
+      if (pC->GetTableName().CmpNoCase(table) == 0
+          && pC->GetGeometryColumn().CmpNoCase(geometry) == 0)
+        {
+          pC->MarkRasterCoverage();
+          break;
+        }
+      pC = pC->GetNext();
+    }
+}
+
+CandidateVectorCoveragesList *MyFrame::FindUnregisteredVectorCoverages()
+{
+// will retrieve all not yet registered Geometries
+  CandidateVectorCoveragesList *list = new CandidateVectorCoveragesList();
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  char *value;
+  const char *sql;
+
+// retrieving all entries from GEOMETRY_COLUMNS
+  sql =
+    "SELECT f_table_name, f_geometry_column, srid, geometry_type "
+    "FROM geometry_columns " "ORDER BY f_table_name, f_geometry_column";
+  int ret = sqlite3_get_table(SqliteHandle, sql, &results,
+                              &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return list;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          value = results[(i * columns) + 0];
+          wxString table = wxString::FromUTF8(value);
+          value = results[(i * columns) + 1];
+          wxString geometry = wxString::FromUTF8(value);
+          value = results[(i * columns) + 2];
+          int srid = atoi(value);
+          value = results[(i * columns) + 3];
+          int gtype = atoi(value);
+          wxString type = wxT("***  UNKNOWN  ***");
+          switch (gtype)
+            {
+              case 0:
+              case 1000:
+              case 2000:
+              case 3000:
+                type = wxT("GEOMETRY");
+                break;
+              case 1:
+              case 1001:
+              case 2001:
+              case 3001:
+                type = wxT("POINT");
+                break;
+              case 2:
+              case 1002:
+              case 2002:
+              case 3002:
+                type = wxT("LINESTRING");
+                break;
+              case 3:
+              case 1003:
+              case 2003:
+              case 3003:
+                type = wxT("POLYGON");
+                break;
+              case 4:
+              case 1004:
+              case 2004:
+              case 3004:
+                type = wxT("MULTIPOINT");
+                break;
+              case 5:
+              case 1005:
+              case 2005:
+              case 3005:
+                type = wxT("MULTILINESTRING");
+                break;
+              case 6:
+              case 1006:
+              case 2006:
+              case 3006:
+                type = wxT("MULTIPOLYGON");
+                break;
+              case 7:
+              case 1007:
+              case 2007:
+              case 3007:
+                type = wxT("GEOMETRYCOLLECTION");
+                break;
+              default:
+                type = wxT("***  UNKNOWN  ***");
+                break;
+            };
+          switch (gtype)
+            {
+              case 0:
+              case 1:
+              case 2:
+              case 3:
+              case 4:
+              case 5:
+              case 6:
+              case 7:
+                type += wxT(" XY");
+                break;
+              case 1000:
+              case 1001:
+              case 1002:
+              case 1003:
+              case 1004:
+              case 1005:
+              case 1006:
+              case 1007:
+                type += wxT(" XYZ");
+                break;
+              case 2000:
+              case 2001:
+              case 2002:
+              case 2003:
+              case 2004:
+              case 2005:
+              case 2006:
+              case 2007:
+                type += wxT(" XYM");
+                break;
+              case 3000:
+              case 3001:
+              case 3002:
+              case 3003:
+              case 3004:
+              case 3005:
+              case 3006:
+              case 3007:
+                type += wxT(" XYZM");
+                break;
+            };
+          list->Add(table, geometry, srid, type);
+        }
+    }
+  sqlite3_free_table(results);
+
+// marking any already registered Vector Coverage
+  sql = "SELECT f_table_name, f_geometry_column FROM vector_coverages";
+  ret = sqlite3_get_table(SqliteHandle, sql, &results,
+                          &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return list;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          value = results[(i * columns) + 0];
+          wxString table = wxString::FromUTF8(value);
+          value = results[(i * columns) + 1];
+          wxString geometry = wxString::FromUTF8(value);
+          list->MarkVectorCoverage(table, geometry);
+        }
+    }
+  sqlite3_free_table(results);
+
+// marking any table related to an already registered Raster Coverage
+  sql = "SELECT coverage_name FROM raster_coverages";
+  ret = sqlite3_get_table(SqliteHandle, sql, &results,
+                          &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return list;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          value = results[(i * columns) + 0];
+          wxString table = wxString::FromUTF8(value) + wxT("_sections");
+          wxString geometry = wxT("geometry");
+          list->MarkRasterCoverage(table, geometry);
+          table = wxString::FromUTF8(value) + wxT("_tiles");
+          list->MarkRasterCoverage(table, geometry);
+        }
+    }
+  sqlite3_free_table(results);
+  return list;
+}
+
+bool MyFrame::DoRegisterVectorCoverage(wxString & name, wxString & table,
+                                       wxString & geometry, wxString & title,
+                                       wxString & abstract)
+{
+//
+// attempting to register a Vector Coverage
+//
+  sqlite3_stmt *stmt = NULL;
+  const char *sql = "SELECT SE_RegisterVectorCoverage(?, ?, ?, ?, ?)";
+  int ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, name.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 2, table.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 3, geometry.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 4, title.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 5, abstract.ToUTF8(), -1, SQLITE_TRANSIENT);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+    ;
+  else
+    {
+      sqlite3_finalize(stmt);
+      return false;
+    }
+  sqlite3_finalize(stmt);
+  return true;
+}
+
+bool VectorCoverageStylesDialog::Create(MyFrame * parent, wxString & coverage)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  int pos = coverage.Find(wxT(" [SRID="));
+  if (pos != wxNOT_FOUND)
+    CoverageName = coverage.Left(pos);
+  else
+    CoverageName = coverage;
+  List = MainFrame->FindVectorCoverageStyles(CoverageName);
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Vector Coverage supported SLD/SE Styles")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void VectorCoverageStylesDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Coverage Name
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_CENTRE_VERTICAL | wxALL, 0);
+  wxStaticText *cvgLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Coverage Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, wxID_ANY, CoverageName,
+                                       wxDefaultPosition, wxSize(350, 22),
+                                       wxTE_READONLY);
+  cvgCtrl->Enable(false);
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered SLD/SE Styles"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_SLD_SE_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  VectorCoverageStyle *pS = List->GetFirst();
+  while (pS)
+    {
+      // counting how many lines are there
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 6, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Style ID"));
+  GridCtrl->SetColLabelValue(1, wxT("Name"));
+  GridCtrl->SetColLabelValue(2, wxT("Title"));
+  GridCtrl->SetColLabelValue(3, wxT("Abstract"));
+  GridCtrl->SetColLabelValue(4, wxT("Schema Validated"));
+  GridCtrl->SetColLabelValue(5, wxT("Schema URI"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pS = List->GetFirst();
+  while (pS)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%d", count + 1);
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetRowLabelValue(count, cell);
+      sprintf(dummy, "%d", pS->GetStyleID());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 0, cell);
+      GridCtrl->SetCellAlignment(count, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 1, pS->GetName());
+      GridCtrl->SetCellValue(count, 2, pS->GetTitle());
+      GridCtrl->SetCellValue(count, 3, pS->GetAbstract());
+      GridCtrl->SetCellValue(count, 4, pS->GetSchemaValidated());
+      GridCtrl->SetCellValue(count, 5, pS->GetSchemaURI());
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *quit = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(quit, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *addNew = new wxButton(this, ID_SLD_SE_ADD, wxT("&Add Style(s)"));
+  btnBox->Add(addNew, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & VectorCoverageStylesDialog::OnQuit);
+  Connect(ID_SLD_SE_ADD, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & VectorCoverageStylesDialog::OnAddStyle);
+  Connect(ID_SLD_SE_REMOVE, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) &
+          VectorCoverageStylesDialog::OnCmdRemoveStyle);
+  Connect(wxID_ANY, wxEVT_GRID_CELL_RIGHT_CLICK,
+          (wxObjectEventFunction) & VectorCoverageStylesDialog::OnRightClick);
+}
+
+void VectorCoverageStylesDialog::OnRightClick(wxGridEvent & event)
+{
+//
+// right click on some cell [mouse action]
+//
+  wxMenu menu;
+  wxMenuItem *menuItem;
+  wxPoint pt = event.GetPosition();
+  CurrentRow = event.GetRow();
+  GridCtrl->SelectRow(CurrentRow);
+  wxString id = GridCtrl->GetCellValue(CurrentRow, 0);
+  long style_id;
+  id.ToLong(&style_id);
+  CurrentStyleID = style_id;
+  menuItem = new wxMenuItem(&menu, ID_SLD_SE_REMOVE, wxT("&Remove"));
+  menu.Append(menuItem);
+  GridCtrl->PopupMenu(&menu, pt);
+}
+
+void VectorCoverageStylesDialog::
+OnCmdRemoveStyle(wxCommandEvent & WXUNUSED(event))
+{
+//
+// deleting a Style [mouse action]
+//
+  sqlite3_stmt *stmt = NULL;
+  const char *sql = "SELECT SE_UnRegisterVectorStyledLayer(?, ?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_int(stmt, 2, CurrentStyleID);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+    GridCtrl->DeleteRows(CurrentRow, 1);
+  sqlite3_finalize(stmt);
+}
+
+void VectorCoverageStylesDialog::
+DoRegistetVectorCoverageStyles(ListVectorStylesDialog * dlg)
+{
+//
+// attempting to register the Vector Coverage Style(s)
+//
+  sqlite3_stmt *stmt = NULL;
+  const char *sql = "SELECT SE_RegisterVectorStyledLayer(?, ?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return;
+
+  int max = dlg->GetSelectedCount();
+  for (int i = 0; i < max; i++)
+    {
+      int style_id = dlg->GetSelectedStyleId(i);
+      if (style_id >= 0)
+        {
+          sqlite3_reset(stmt);
+          sqlite3_clear_bindings(stmt);
+          sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1,
+                            SQLITE_TRANSIENT);
+          sqlite3_bind_int(stmt, 2, style_id);
+          ret = sqlite3_step(stmt);
+          if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+            ;
+          else
+            {
+              sqlite3_finalize(stmt);
+              return;
+            }
+        }
+    }
+  sqlite3_finalize(stmt);
+}
+
+void VectorCoverageStylesDialog::OnAddStyle(wxCommandEvent & WXUNUSED(event))
+{
+//
+// adding a new Style [button action]
+//
+  ListVectorStylesDialog dlg;
+  dlg.Create(MainFrame);
+  if (dlg.ShowModal() == wxID_OK)
+    {
+      // attempting to register the new styles
+      DoRegistetVectorCoverageStyles(&dlg);
+
+      // updating the Grid
+      int tot_rows = GridCtrl->GetNumberRows();
+      GridCtrl->DeleteRows(0, tot_rows);
+      if (List != NULL)
+        delete List;
+      List = MainFrame->FindVectorCoverageStyles(CoverageName);
+      int count = 0;
+      VectorCoverageStyle *pS = List->GetFirst();
+      while (pS)
+        {
+          // counting how many lines are there
+          count++;
+          pS = pS->GetNext();
+        }
+      GridCtrl->AppendRows(count);
+      count = 0;
+      char dummy[1024];
+      wxString cell;
+      pS = List->GetFirst();
+      while (pS)
+        {
+          // feeding grid rows
+          sprintf(dummy, "%d", count + 1);
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetRowLabelValue(count, cell);
+          sprintf(dummy, "%d", pS->GetStyleID());
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetCellValue(count, 0, cell);
+          GridCtrl->SetCellAlignment(count, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+          GridCtrl->SetCellValue(count, 1, pS->GetName());
+          GridCtrl->SetCellValue(count, 2, pS->GetTitle());
+          GridCtrl->SetCellValue(count, 3, pS->GetAbstract());
+          GridCtrl->SetCellValue(count, 4, pS->GetSchemaValidated());
+          GridCtrl->SetCellValue(count, 5, pS->GetSchemaURI());
+          count++;
+          pS = pS->GetNext();
+        }
+      GridCtrl->AutoSizeColumns();
+    }
+}
+
+void VectorCoverageStylesDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool ListVectorStylesDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  List = MainFrame->FindVectorStyles();
+  if (wxDialog::Create(parent, wxID_ANY, wxT("Registered SLD/SE Vector Styles"))
+      == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void ListVectorStylesDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered SLD/SE Styles"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_SLD_SE_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  VectorCoverageStyle *pS = List->GetFirst();
+  while (pS)
+    {
+      // counting how many lines are there
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 6, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Style ID"));
+  GridCtrl->SetColLabelValue(1, wxT("Name"));
+  GridCtrl->SetColLabelValue(2, wxT("Title"));
+  GridCtrl->SetColLabelValue(3, wxT("Abstract"));
+  GridCtrl->SetColLabelValue(4, wxT("Schema Validated"));
+  GridCtrl->SetColLabelValue(5, wxT("Schema URI"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pS = List->GetFirst();
+  while (pS)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%d", count + 1);
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetRowLabelValue(count, cell);
+      sprintf(dummy, "%d", pS->GetStyleID());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 0, cell);
+      GridCtrl->SetCellAlignment(count, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 1, pS->GetName());
+      GridCtrl->SetCellValue(count, 2, pS->GetTitle());
+      GridCtrl->SetCellValue(count, 3, pS->GetAbstract());
+      GridCtrl->SetCellValue(count, 4, pS->GetSchemaValidated());
+      GridCtrl->SetCellValue(count, 5, pS->GetSchemaURI());
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Ok"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel"));
+  btnBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & ListVectorStylesDialog::OnOk);
+}
+
+int ListVectorStylesDialog::GetSelectedCount()
+{
+//
+// computing how many selected Style there are
+//
+  int count = 0;
+  VectorCoverageStyle *pS = List->GetFirst();
+  while (pS != NULL)
+    {
+      if (pS->IsSelected() == true)
+        count++;
+      pS = pS->GetNext();
+    }
+  return count;
+}
+
+int ListVectorStylesDialog::GetSelectedStyleId(int idx)
+{
+//
+// returning the Nth selected StyleID
+//
+  int count = 0;
+  VectorCoverageStyle *pS = List->GetFirst();
+  while (pS != NULL)
+    {
+      if (pS->IsSelected() == true)
+        {
+          if (count == idx)
+            return pS->GetStyleID();
+          count++;
+        }
+      pS = pS->GetNext();
+    }
+  return -1;
+}
+
+void ListVectorStylesDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  for (int i = 0; i < GridCtrl->GetNumberRows(); i++)
+    {
+      if (GridCtrl->IsInSelection(i, 0) == true)
+        {
+          wxString cell_id = GridCtrl->GetCellValue(i, 0);
+          long style_id;
+          if (cell_id.ToLong(&style_id) == true)
+            List->MarkSelected(style_id);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+VectorCoverageStyle::VectorCoverageStyle(int style_id, wxString & name,
+                                         wxString & title, wxString & abstract,
+                                         wxString & validated,
+                                         wxString & schema_uri)
+{
+// constructor
+  StyleID = style_id;
+  Name = name;
+  Title = title;
+  Abstract = abstract;
+  SchemaValidated = validated;
+  SchemaURI = schema_uri;
+  Selected = false;
+  Next = NULL;
+}
+
+VectorCoverageStylesList::VectorCoverageStylesList()
+{
+// constructor
+  First = NULL;
+  Last = NULL;
+}
+
+VectorCoverageStylesList::~VectorCoverageStylesList()
+{
+// destructor
+  VectorCoverageStyle *pS;
+  VectorCoverageStyle *pSn;
+  pS = First;
+  while (pS != NULL)
+    {
+      pSn = pS->GetNext();
+      delete pS;
+      pS = pSn;
+    }
+}
+
+void VectorCoverageStylesList::Add(int style_id, wxString & name,
+                                   wxString & title, wxString & abstract,
+                                   wxString & validated, wxString & schema_uri)
+{
+// inserting a new Style
+  VectorCoverageStyle *pS =
+    new VectorCoverageStyle(style_id, name, title, abstract, validated,
+                            schema_uri);
+  if (First == NULL)
+    First = pS;
+  if (Last != NULL)
+    Last->SetNext(pS);
+  Last = pS;
+}
+
+void VectorCoverageStylesList::MarkSelected(int styleId)
+{
+// marking a Selected Style
+  VectorCoverageStyle *pS;
+  pS = First;
+  while (pS != NULL)
+    {
+      if (pS->GetStyleID() == styleId)
+        {
+          pS->MarkSelected();
+          break;
+        }
+      pS = pS->GetNext();
+    }
+}
+
+VectorCoverageStylesList *MyFrame::FindVectorCoverageStyles(wxString & coverage)
+{
+// will retrieve all SLD/SE Styles for the given Coverage
+  VectorCoverageStylesList *list = new VectorCoverageStylesList();
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  char *value;
+  wxString sql;
+
+  sql =
+    wxT
+    ("SELECT style_id, name, title, abstract, schema_validated, schema_uri ");
+  sql +=
+    wxT("FROM SE_Vector_styled_layers_view WHERE coverage_name = '") + coverage;
+  sql += wxT("' ORDER BY style_id");
+  int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
+                              &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return list;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          value = results[(i * columns) + 0];
+          int style_id = atoi(value);
+          value = results[(i * columns) + 1];
+          wxString name = wxString::FromUTF8(value);
+          value = results[(i * columns) + 2];
+          wxString title = wxString::FromUTF8(value);
+          value = results[(i * columns) + 3];
+          wxString abstract = wxString::FromUTF8(value);
+          value = results[(i * columns) + 1];
+          wxString validated = wxT("Yes");
+          if (atoi(value) == 0)
+            validated = wxT("No");
+          value = results[(i * columns) + 5];
+          wxString schema_uri = wxString::FromUTF8(value);
+          list->Add(style_id, name, title, abstract, validated, schema_uri);
+        }
+    }
+  sqlite3_free_table(results);
+  return list;
+}
+
+VectorCoverageStylesList *MyFrame::FindVectorStyles()
+{
+// will retrieve all registered SLD/SE Vector Styles
+  VectorCoverageStylesList *list = new VectorCoverageStylesList();
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  char *value;
+  const char *sql;
+
+  sql =
+    "SELECT style_id, style_name, XB_GetTitle(style), XB_GetAbstract(style), "
+    "XB_IsSchemaValidated(style), XB_GetSchemaURI(style) "
+    "FROM SE_Vector_styles ORDER BY style_name";
+  int ret = sqlite3_get_table(SqliteHandle, sql, &results,
+                              &rows, &columns, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return list;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          value = results[(i * columns) + 0];
+          int style_id = atoi(value);
+          value = results[(i * columns) + 1];
+          wxString name = wxString::FromUTF8(value);
+          value = results[(i * columns) + 2];
+          wxString title = wxString::FromUTF8(value);
+          value = results[(i * columns) + 3];
+          wxString abstract = wxString::FromUTF8(value);
+          value = results[(i * columns) + 1];
+          wxString validated = wxT("Yes");
+          if (atoi(value) == 0)
+            validated = wxT("No");
+          value = results[(i * columns) + 5];
+          wxString schema_uri = wxString::FromUTF8(value);
+          list->Add(style_id, name, title, abstract, validated, schema_uri);
+        }
+    }
+  sqlite3_free_table(results);
+  return list;
+}
+
+bool VectorRegisterDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  List = MainFrame->FindUnregisteredVectorCoverages();
+  if (wxDialog::Create(parent, wxID_ANY, wxT("Register Vector Coverage"))
+      == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  int count = 0;
+  CandidateVectorCoverage *pC = List->GetFirst();
+  while (pC)
+    {
+      // counting how many lines are there
+      if (pC->IsVectorCoverage() != true && pC->IsRasterCoverage() != true)
+        count++;
+      pC = pC->GetNext();
+    }
+  if (count == 0)
+    {
+      wxButton *ok = (wxButton *) FindWindow(wxID_OK);
+      ok->Enable(false);
+      wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_VECTOR_COVERAGE);
+      nameCtrl->Enable(false);
+      wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_VECTOR_TITLE);
+      titleCtrl->Enable(false);
+      wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_VECTOR_ABSTRACT);
+      absCtrl->Enable(false);
+      wxMessageBox(wxT
+                   ("There are no possible Candidates to be eventually registered"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+    }
+  return true;
+}
+
+void VectorRegisterDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Candidate Vector Coverages"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_VECTOR_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  CandidateVectorCoverage *pC = List->GetFirst();
+  while (pC)
+    {
+      // counting how many lines are there
+      if (pC->IsVectorCoverage() != true && pC->IsRasterCoverage() != true)
+        count++;
+      pC = pC->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 4, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("f_table_name"));
+  GridCtrl->SetColLabelValue(1, wxT("f_geometry_column"));
+  GridCtrl->SetColLabelValue(2, wxT("SRID"));
+  GridCtrl->SetColLabelValue(3, wxT("GeometryType"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pC = List->GetFirst();
+  while (pC)
+    {
+      // feeding grid rows
+      if (pC->IsVectorCoverage() != true && pC->IsRasterCoverage() != true)
+        {
+          sprintf(dummy, "%d", count + 1);
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetRowLabelValue(count, cell);
+          GridCtrl->SetCellValue(count, 0, pC->GetTableName());
+          GridCtrl->SetCellValue(count, 1, pC->GetGeometryColumn());
+          sprintf(dummy, "%d", pC->GetSrid());
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetCellValue(count, 2, cell);
+          GridCtrl->SetCellAlignment(count, 2, wxALIGN_RIGHT, wxALIGN_CENTRE);
+          GridCtrl->SetCellValue(count, 3, pC->GetGeometryType());
+          count++;
+        }
+      pC = pC->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the Coverage Name
+  wxBoxSizer *nameSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(nameSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *nameLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Coverage Name:"));
+  nameSizer->Add(nameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *nameCtrl = new wxTextCtrl(this, ID_VECTOR_COVERAGE, wxT(""),
+                                        wxDefaultPosition, wxSize(550, 22));
+  nameSizer->Add(nameCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the Coverage Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(this, ID_VECTOR_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(550, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: the Coverage Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl = new wxTextCtrl(this, ID_VECTOR_ABSTRACT, wxT(""),
+                                            wxDefaultPosition, wxSize(550, 60),
+                                            wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Register"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel"));
+  btnBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & VectorRegisterDialog::OnOk);
+}
+
+void VectorRegisterDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_VECTOR_COVERAGE);
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_VECTOR_TITLE);
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_VECTOR_ABSTRACT);
+  wxString str = nameCtrl->GetValue().Trim();
+  CoverageName = str.Trim(false);
+  if (CoverageName.Len() == 0)
+    {
+      wxMessageBox(wxT("You must specify some Coverage Name !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  str = titleCtrl->GetValue().Trim();
+  Title = str.Trim(false);
+  if (Title.Len() == 0)
+    {
+      wxMessageBox(wxT("You must specify some Title !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  str = absCtrl->GetValue().Trim();
+  Abstract = str.Trim(false);
+  if (Abstract.Len() == 0)
+    {
+      wxMessageBox(wxT("You must specify some Abstract !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  int selCount = 0;
+  for (int i = 0; i < GridCtrl->GetNumberRows(); i++)
+    {
+      if (GridCtrl->IsInSelection(i, 0) == true)
+        {
+          TableName = GridCtrl->GetCellValue(i, 0);
+          GeometryColumn = GridCtrl->GetCellValue(i, 1);
+          selCount++;
+        }
+    }
+  if (selCount < 1)
+    {
+      wxMessageBox(wxT("You must select a Candidate to be registered !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (selCount > 1)
+    {
+      wxString msg =
+        wxT("You must select just a single Candidate to be registered !!!\n");
+      msg += wxT("Multiple selection is not supported");
+      wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool ReloadVectorStyleDialog::Create(MyFrame * parent, wxString & path)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Path = path;
+  List = MainFrame->FindVectorStyles();
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Reloading an SLD/SE Vector Style")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void ReloadVectorStyleDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Style's Path
+  wxBoxSizer *pathSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(pathSizer, 0, wxALIGN_CENTRE_VERTICAL | wxALL, 0);
+  wxStaticText *pathLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&SLD/SE Style:"));
+  pathSizer->Add(pathLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *pathCtrl = new wxTextCtrl(this, wxID_ANY, Path,
+                                        wxDefaultPosition, wxSize(550, 22),
+                                        wxTE_READONLY);
+  pathCtrl->Enable(false);
+  pathSizer->Add(pathCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered SLD/SE Vector Styles"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_SLD_SE_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  VectorCoverageStyle *pS = List->GetFirst();
+  while (pS)
+    {
+      // counting how many lines are there
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 6, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Style ID"));
+  GridCtrl->SetColLabelValue(1, wxT("Name"));
+  GridCtrl->SetColLabelValue(2, wxT("Title"));
+  GridCtrl->SetColLabelValue(3, wxT("Abstract"));
+  GridCtrl->SetColLabelValue(4, wxT("Schema Validated"));
+  GridCtrl->SetColLabelValue(5, wxT("Schema URI"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pS = List->GetFirst();
+  while (pS)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%d", count + 1);
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetRowLabelValue(count, cell);
+      sprintf(dummy, "%d", pS->GetStyleID());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 0, cell);
+      GridCtrl->SetCellAlignment(count, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 1, pS->GetName());
+      GridCtrl->SetCellValue(count, 2, pS->GetTitle());
+      GridCtrl->SetCellValue(count, 3, pS->GetAbstract());
+      GridCtrl->SetCellValue(count, 4, pS->GetSchemaValidated());
+      GridCtrl->SetCellValue(count, 5, pS->GetSchemaURI());
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Reload"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel"));
+  btnBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & ReloadVectorStyleDialog::OnOk);
+}
+
+bool ReloadVectorStyleDialog::DoReloadVectorStyle(int style_id, void *blob,
+                                                  int blob_size)
+{
+//
+// attempting to reload the Vector Style
+//
+  int ret;
+  int valid = 0;
+  const char *sql;
+  sqlite3_stmt *stmt = NULL;
+
+  sql = "SELECT SE_ReloadVectorStyle(?, ?)";
+  ret =
+    sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_int(stmt, 1, style_id);
+  sqlite3_bind_blob(stmt, 2, blob, blob_size, free);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (valid)
+    return true;
+  return false;
+}
+
+void ReloadVectorStyleDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  int selCount = 0;
+  long style_id;
+  void *blob = NULL;
+  int blob_size;
+  for (int i = 0; i < GridCtrl->GetNumberRows(); i++)
+    {
+      if (GridCtrl->IsInSelection(i, 0) == true)
+        {
+          wxString cell_id = GridCtrl->GetCellValue(i, 0);
+          if (cell_id.ToLong(&style_id) == true)
+            selCount++;
+        }
+    }
+  if (selCount < 1)
+    {
+      wxMessageBox(wxT("You must select a Vector Style to be reloaded !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (selCount > 1)
+    {
+      wxString msg =
+        wxT("You must select just a single Vector Style to be reloaded !!!\n");
+      msg += wxT("Multiple selection is not supported");
+      wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  ::wxBeginBusyCursor();
+  if (MainFrame->ValidateVectorStyle(Path.ToUTF8(), &blob, &blob_size) == true)
+    {
+      char dummy[80];
+      sprintf(dummy, "%d", style_id);
+      if (DoReloadVectorStyle(style_id, blob, blob_size) == true)
+        {
+          ::wxEndBusyCursor();
+          wxMessageBox(wxT("Vector Style (style_id=") +
+                       wxString::FromUTF8(dummy) +
+                       wxT(") successfully reloaded"), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+      } else
+        {
+          ::wxEndBusyCursor();
+          wxMessageBox(wxT
+                       ("Some error occurred: unable to reload Vector Style (style_id=")
+                       + wxString::FromUTF8(dummy) + wxT(")"),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+        }
+  } else
+    {
+      ::wxEndBusyCursor();
+      wxString msg = Path + wxT("\n\nnot a valid SLD/SE Vector Style");
+      wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool ReloadRasterStyleDialog::Create(MyFrame * parent, wxString & path)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Path = path;
+  List = MainFrame->FindRasterStyles();
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Reloading an SLD/SE Raster Style")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void ReloadRasterStyleDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Style's Path
+  wxBoxSizer *pathSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(pathSizer, 0, wxALIGN_CENTRE_VERTICAL | wxALL, 0);
+  wxStaticText *pathLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&SLD/SE Style:"));
+  pathSizer->Add(pathLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *pathCtrl = new wxTextCtrl(this, wxID_ANY, Path,
+                                        wxDefaultPosition, wxSize(550, 22),
+                                        wxTE_READONLY);
+  pathCtrl->Enable(false);
+  pathSizer->Add(pathCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered SLD/SE Raster Styles"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_SLD_SE_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  RasterCoverageStyle *pS = List->GetFirst();
+  while (pS)
+    {
+      // counting how many lines are there
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 6, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Style ID"));
+  GridCtrl->SetColLabelValue(1, wxT("Name"));
+  GridCtrl->SetColLabelValue(2, wxT("Title"));
+  GridCtrl->SetColLabelValue(3, wxT("Abstract"));
+  GridCtrl->SetColLabelValue(4, wxT("Schema Validated"));
+  GridCtrl->SetColLabelValue(5, wxT("Schema URI"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pS = List->GetFirst();
+  while (pS)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%d", count + 1);
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetRowLabelValue(count, cell);
+      sprintf(dummy, "%d", pS->GetStyleID());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 0, cell);
+      GridCtrl->SetCellAlignment(count, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 1, pS->GetName());
+      GridCtrl->SetCellValue(count, 2, pS->GetTitle());
+      GridCtrl->SetCellValue(count, 3, pS->GetAbstract());
+      GridCtrl->SetCellValue(count, 4, pS->GetSchemaValidated());
+      GridCtrl->SetCellValue(count, 5, pS->GetSchemaURI());
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Reload"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel"));
+  btnBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & ReloadRasterStyleDialog::OnOk);
+}
+
+bool ReloadRasterStyleDialog::DoReloadRasterStyle(int style_id, void *blob,
+                                                  int blob_size)
+{
+//
+// attempting to reload the Raster Style
+//
+  int ret;
+  int valid = 0;
+  const char *sql;
+  sqlite3_stmt *stmt = NULL;
+
+  sql = "SELECT SE_ReloadRasterStyle(?, ?)";
+  ret =
+    sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_int(stmt, 1, style_id);
+  sqlite3_bind_blob(stmt, 2, blob, blob_size, free);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (valid)
+    return true;
+  return false;
+}
+
+void ReloadRasterStyleDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  int selCount = 0;
+  long style_id;
+  void *blob = NULL;
+  int blob_size;
+  for (int i = 0; i < GridCtrl->GetNumberRows(); i++)
+    {
+      if (GridCtrl->IsInSelection(i, 0) == true)
+        {
+          wxString cell_id = GridCtrl->GetCellValue(i, 0);
+          if (cell_id.ToLong(&style_id) == true)
+            selCount++;
+        }
+    }
+  if (selCount < 1)
+    {
+      wxMessageBox(wxT("You must select a Raster Style to be reloaded !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (selCount > 1)
+    {
+      wxString msg =
+        wxT("You must select just a single Raster Style to be reloaded !!!\n");
+      msg += wxT("Multiple selection is not supported");
+      wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  ::wxBeginBusyCursor();
+  if (MainFrame->ValidateRasterStyle(Path.ToUTF8(), &blob, &blob_size) == true)
+    {
+      char dummy[80];
+      sprintf(dummy, "%d", style_id);
+      if (DoReloadRasterStyle(style_id, blob, blob_size) == true)
+        {
+          ::wxEndBusyCursor();
+          wxMessageBox(wxT("Raster Style (style_id=") +
+                       wxString::FromUTF8(dummy) +
+                       wxT(") successfully reloaded"), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+      } else
+        {
+          ::wxEndBusyCursor();
+          wxMessageBox(wxT
+                       ("Some error occurred: unable to reload Raster Style (style_id=")
+                       + wxString::FromUTF8(dummy) + wxT(")"),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+        }
+  } else
+    {
+      ::wxEndBusyCursor();
+      wxString msg = Path + wxT("\n\nnot a valid SLD/SE Raster Style");
+      wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool UnregisterRasterStyleDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  List = MainFrame->FindRasterStyles();
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Unregistering an SLD/SE Raster Style")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void UnregisterRasterStyleDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered SLD/SE Raster Styles"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_SLD_SE_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  RasterCoverageStyle *pS = List->GetFirst();
+  while (pS)
+    {
+      // counting how many lines are there
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 6, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Style ID"));
+  GridCtrl->SetColLabelValue(1, wxT("Name"));
+  GridCtrl->SetColLabelValue(2, wxT("Title"));
+  GridCtrl->SetColLabelValue(3, wxT("Abstract"));
+  GridCtrl->SetColLabelValue(4, wxT("Schema Validated"));
+  GridCtrl->SetColLabelValue(5, wxT("Schema URI"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pS = List->GetFirst();
+  while (pS)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%d", count + 1);
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetRowLabelValue(count, cell);
+      sprintf(dummy, "%d", pS->GetStyleID());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 0, cell);
+      GridCtrl->SetCellAlignment(count, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 1, pS->GetName());
+      GridCtrl->SetCellValue(count, 2, pS->GetTitle());
+      GridCtrl->SetCellValue(count, 3, pS->GetAbstract());
+      GridCtrl->SetCellValue(count, 4, pS->GetSchemaValidated());
+      GridCtrl->SetCellValue(count, 5, pS->GetSchemaURI());
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Unregister"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel"));
+  btnBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & UnregisterRasterStyleDialog::OnOk);
+}
+
+bool UnregisterRasterStyleDialog::DoUnregisterRasterStyle(int style_id)
+{
+//
+// attempting to unregister the Raster Style
+//
+  int ret;
+  int valid = 0;
+  const char *sql;
+  sqlite3_stmt *stmt = NULL;
+
+  sql = "SELECT SE_UnregisterRasterStyle(?)";
+  ret =
+    sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_int(stmt, 1, style_id);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (valid)
+    return true;
+  return false;
+}
+
+bool UnregisterRasterStyleDialog::DoCheckUnreferencedRasterStyle(int style_id)
+{
+//
+// checking if a Raster Style is currently referenced or not
+//
+  int ret;
+  int count = 1;
+  const char *sql;
+  sqlite3_stmt *stmt = NULL;
+
+  sql = "SELECT Count(*) FROM SE_raster_styles AS s "
+    "JOIN SE_raster_styled_layers AS l ON (l.style_id = s.style_id) "
+    "WHERE s.style_id = ?";
+  ret =
+    sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_int(stmt, 1, style_id);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            count = sqlite3_column_int(stmt, 0);
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (!count)
+    return true;
+  return false;
+}
+
+void UnregisterRasterStyleDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  int selCount = 0;
+  long style_id;
+  for (int i = 0; i < GridCtrl->GetNumberRows(); i++)
+    {
+      if (GridCtrl->IsInSelection(i, 0) == true)
+        {
+          wxString cell_id = GridCtrl->GetCellValue(i, 0);
+          if (cell_id.ToLong(&style_id) == true)
+            selCount++;
+        }
+    }
+  if (selCount < 1)
+    {
+      wxMessageBox(wxT("You must select a Raster Style to be unregistered !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (selCount > 1)
+    {
+      wxString msg =
+        wxT
+        ("You must select just a single Raster Style to be unregistered !!!\n");
+      msg += wxT("Multiple selection is not supported");
+      wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  ::wxBeginBusyCursor();
+  char dummy[80];
+  sprintf(dummy, "%d", style_id);
+  if (DoCheckUnreferencedRasterStyle(style_id) == true)
+    {
+      if (DoUnregisterRasterStyle(style_id) == true)
+        {
+          ::wxEndBusyCursor();
+          wxMessageBox(wxT("Raster Style (style_id=") +
+                       wxString::FromUTF8(dummy) +
+                       wxT(") successfully unregistered"),
+                       wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+      } else
+        {
+          ::wxEndBusyCursor();
+          wxMessageBox(wxT
+                       ("Some error occurred: unable to unregister Raster Style (style_id=")
+                       + wxString::FromUTF8(dummy) + wxT(")"),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+        }
+  } else
+    {
+      ::wxEndBusyCursor();
+      wxMessageBox(wxT("You can't unregister Raster Style (style_id=") +
+                   wxString::FromUTF8(dummy) +
+                   wxT
+                   (")\nbecause it's currently referenced by at least one Raster Coverage"),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool UnregisterVectorStyleDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  List = MainFrame->FindVectorStyles();
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Unregistering an SLD/SE Vector Style")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void UnregisterVectorStyleDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered SLD/SE Vector Styles"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_SLD_SE_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  VectorCoverageStyle *pS = List->GetFirst();
+  while (pS)
+    {
+      // counting how many lines are there
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 6, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Style ID"));
+  GridCtrl->SetColLabelValue(1, wxT("Name"));
+  GridCtrl->SetColLabelValue(2, wxT("Title"));
+  GridCtrl->SetColLabelValue(3, wxT("Abstract"));
+  GridCtrl->SetColLabelValue(4, wxT("Schema Validated"));
+  GridCtrl->SetColLabelValue(5, wxT("Schema URI"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pS = List->GetFirst();
+  while (pS)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%d", count + 1);
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetRowLabelValue(count, cell);
+      sprintf(dummy, "%d", pS->GetStyleID());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 0, cell);
+      GridCtrl->SetCellAlignment(count, 0, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 1, pS->GetName());
+      GridCtrl->SetCellValue(count, 2, pS->GetTitle());
+      GridCtrl->SetCellValue(count, 3, pS->GetAbstract());
+      GridCtrl->SetCellValue(count, 4, pS->GetSchemaValidated());
+      GridCtrl->SetCellValue(count, 5, pS->GetSchemaURI());
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Unregister"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel"));
+  btnBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & UnregisterVectorStyleDialog::OnOk);
+}
+
+bool UnregisterVectorStyleDialog::DoUnregisterVectorStyle(int style_id)
+{
+//
+// attempting to unregister the Vector Style
+//
+  int ret;
+  int valid = 0;
+  const char *sql;
+  sqlite3_stmt *stmt = NULL;
+
+  sql = "SELECT SE_UnregisterVectorStyle(?)";
+  ret =
+    sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_int(stmt, 1, style_id);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (valid)
+    return true;
+  return false;
+}
+
+bool UnregisterVectorStyleDialog::DoCheckUnreferencedVectorStyle(int style_id)
+{
+//
+// checking if a Vector Style is currently referenced or not
+//
+  int ret;
+  int count = 1;
+  const char *sql;
+  sqlite3_stmt *stmt = NULL;
+
+  sql = "SELECT Count(*) FROM SE_vector_styles AS s "
+    "JOIN SE_vector_styled_layers AS l ON (l.style_id = s.style_id) "
+    "WHERE s.style_id = ?";
+  ret =
+    sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_int(stmt, 1, style_id);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            count = sqlite3_column_int(stmt, 0);
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (!count)
+    return true;
+  return false;
+}
+
+void UnregisterVectorStyleDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  int selCount = 0;
+  long style_id;
+  for (int i = 0; i < GridCtrl->GetNumberRows(); i++)
+    {
+      if (GridCtrl->IsInSelection(i, 0) == true)
+        {
+          wxString cell_id = GridCtrl->GetCellValue(i, 0);
+          if (cell_id.ToLong(&style_id) == true)
+            selCount++;
+        }
+    }
+  if (selCount < 1)
+    {
+      wxMessageBox(wxT("You must select a Vector Style to be unregistered !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (selCount > 1)
+    {
+      wxString msg =
+        wxT
+        ("You must select just a single Vector Style to be unregistered !!!\n");
+      msg += wxT("Multiple selection is not supported");
+      wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  ::wxBeginBusyCursor();
+  char dummy[80];
+  sprintf(dummy, "%d", style_id);
+  if (DoCheckUnreferencedVectorStyle(style_id) == true)
+    {
+      if (DoUnregisterVectorStyle(style_id) == true)
+        {
+          ::wxEndBusyCursor();
+          wxMessageBox(wxT("Vector Style (style_id=") +
+                       wxString::FromUTF8(dummy) +
+                       wxT(") successfully unregistered"),
+                       wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+      } else
+        {
+          ::wxEndBusyCursor();
+          wxMessageBox(wxT
+                       ("Some error occurred: unable to unregister Vector Style (style_id=")
+                       + wxString::FromUTF8(dummy) + wxT(")"),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+        }
+  } else
+    {
+      ::wxEndBusyCursor();
+      wxMessageBox(wxT("You can't unregister Vector Style (style_id=") +
+                   wxString::FromUTF8(dummy) +
+                   wxT
+                   (")\nbecause it's currently referenced by at least one Vector Coverage"),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool VectorSRIDsDialog::Create(MyFrame * parent, wxString & coverage)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  int pos = coverage.Find(wxT(" [SRID="));
+  if (pos != wxNOT_FOUND)
+    CoverageName = coverage.Left(pos);
+  else
+    CoverageName = coverage;
+  List = MainFrame->FindVectorAlternativeSRIDs(CoverageName);
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Vector Coverage: alternative SRIDs")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void VectorSRIDsDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Vector Coverage
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_CENTRE_VERTICAL | wxALL, 0);
+  wxStaticText *cvgLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Coverage Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, wxID_ANY, CoverageName,
+                                       wxDefaultPosition, wxSize(550, 22),
+                                       wxTE_READONLY);
+  cvgCtrl->Enable(false);
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered alternative SRIDs"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_VECTOR_SRID_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  VectorCoverageSRID *pS = List->GetFirst();
+  while (pS)
+    {
+      // counting how many lines are there
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 5, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Native"));
+  GridCtrl->SetColLabelValue(1, wxT("SRID"));
+  GridCtrl->SetColLabelValue(2, wxT("Auth Name"));
+  GridCtrl->SetColLabelValue(3, wxT("Auth SRID"));
+  GridCtrl->SetColLabelValue(4, wxT("RefSys Name"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pS = List->GetFirst();
+  while (pS)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%d", count + 1);
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetRowLabelValue(count, cell);
+      if (pS->IsNative() == true)
+        GridCtrl->SetCellValue(count, 0, wxT("yes"));
+      else
+        GridCtrl->SetCellValue(count, 0, wxT(""));
+      sprintf(dummy, "%d", pS->GetSrid());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 1, cell);
+      GridCtrl->SetCellAlignment(count, 1, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 2, pS->GetAuthName());
+      sprintf(dummy, "%d", pS->GetAuthSrid());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 3, cell);
+      GridCtrl->SetCellAlignment(count, 3, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 4, pS->GetRefSysName());
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// SRID selection
+  wxBoxSizer *sridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(sridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *sridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Adding an alternative SRID"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *SridSizer = new wxStaticBoxSizer(sridBox, wxHORIZONTAL);
+  sridBoxSizer->Add(SridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *sridSizer = new wxBoxSizer(wxHORIZONTAL);
+  SridSizer->Add(sridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *sridLabel = new wxStaticText(this, wxID_STATIC, wxT("&SRID:"));
+  sridSizer->Add(sridLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  int srid = 0;
+  wxSpinCtrl *sridCtrl = new wxSpinCtrl(this, ID_VECTOR_SRID, wxEmptyString,
+                                        wxDefaultPosition, wxSize(80, 20),
+                                        wxSP_ARROW_KEYS,
+                                        -1, 1000000, srid);
+  sridSizer->Add(sridCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  sridSizer->AddSpacer(100);
+  wxButton *addNew = new wxButton(this, ID_VECTOR_SRID_ADD, wxT("&Add SRID"));
+  sridSizer->Add(addNew, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & VectorSRIDsDialog::OnQuit);
+  Connect(ID_VECTOR_SRID_ADD, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & VectorSRIDsDialog::OnCmdAddSrid);
+  Connect(ID_VECTOR_SRID_REMOVE, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & VectorSRIDsDialog::OnCmdRemoveSrid);
+  Connect(wxID_ANY, wxEVT_GRID_CELL_RIGHT_CLICK,
+          (wxObjectEventFunction) & VectorSRIDsDialog::OnRightClick);
+}
+
+void VectorSRIDsDialog::OnRightClick(wxGridEvent & event)
+{
+//
+// right click on some cell [mouse action]
+//
+  wxMenu menu;
+  wxMenuItem *menuItem;
+  wxPoint pt = event.GetPosition();
+  CurrentRow = event.GetRow();
+  GridCtrl->SelectRow(CurrentRow);
+  wxString native = GridCtrl->GetCellValue(CurrentRow, 0);
+  if (native.CmpNoCase(wxT("yes")) == 0)
+    return;
+  wxString id = GridCtrl->GetCellValue(CurrentRow, 1);
+  long srid;
+  id.ToLong(&srid);
+  CurrentSRID = srid;
+  menuItem = new wxMenuItem(&menu, ID_VECTOR_SRID_REMOVE, wxT("&Remove"));
+  menu.Append(menuItem);
+  GridCtrl->PopupMenu(&menu, pt);
+}
+
+void VectorSRIDsDialog::OnCmdRemoveSrid(wxCommandEvent & WXUNUSED(event))
+{
+//
+// deleting a SRID [mouse action]
+//
+  sqlite3_stmt *stmt = NULL;
+  const char *sql = "SELECT SE_UnRegisterVectorCoverageSrid(?, ?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_int(stmt, 2, CurrentSRID);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+    {
+      GridCtrl->DeleteRows(CurrentRow, 1);
+      List->MarkDeleted(CurrentSRID);
+    }
+  sqlite3_finalize(stmt);
+}
+
+bool VectorSRIDsDialog::DoRegistetVectorCoverageSrid(int srid)
+{
+//
+// attempting to register an alternative Vector Coverage SRID
+//
+  sqlite3_stmt *stmt = NULL;
+  int value = 0;
+  const char *sql = "SELECT SE_RegisterVectorCoverageSrid(?, ?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_int(stmt, 2, srid);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE)
+    ;
+  else if (ret == SQLITE_ROW)
+    value = sqlite3_column_int(stmt, 0);
+  else
+    {
+      sqlite3_finalize(stmt);
+      return false;
+    }
+  sqlite3_finalize(stmt);
+  if (!value)
+    return false;
+  return true;
+}
+
+void VectorSRIDsDialog::OnCmdAddSrid(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxSpinCtrl *sridCtrl = (wxSpinCtrl *) FindWindow(ID_VECTOR_SRID);
+  int srid = sridCtrl->GetValue();
+  if (srid <= 0)
+    {
+      wxMessageBox(wxT("You must specify some SRID value !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+  } else if (MainFrame->SridNotExists(srid) == true)
+    {
+      wxMessageBox(wxT("invalid SRID value"), wxT("spatialite_gui"),
+                   wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (List->IsNativeSrid(srid) == true)
+    {
+      wxMessageBox(wxT("Can't register twice the Native SRID"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (List->IsAlreadyDefinedSrid(srid) == true)
+    {
+      wxMessageBox(wxT("Already defined alternative SRID"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  // attempting to register the alternative SRID
+  if (DoRegistetVectorCoverageSrid(srid) == true)
+    {
+      // updating the Grid
+      int tot_rows = GridCtrl->GetNumberRows();
+      GridCtrl->DeleteRows(0, tot_rows);
+      if (List != NULL)
+        delete List;
+      List = MainFrame->FindVectorAlternativeSRIDs(CoverageName);
+      int count = 0;
+      VectorCoverageSRID *pS = List->GetFirst();
+      while (pS)
+        {
+          // counting how many lines are there
+          count++;
+          pS = pS->GetNext();
+        }
+      GridCtrl->AppendRows(count);
+      count = 0;
+      char dummy[1024];
+      wxString cell;
+      pS = List->GetFirst();
+      while (pS)
+        {
+          // feeding grid rows
+          sprintf(dummy, "%d", count + 1);
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetRowLabelValue(count, cell);
+          if (pS->IsNative() == true)
+            GridCtrl->SetCellValue(count, 0, wxT("yes"));
+          else
+            GridCtrl->SetCellValue(count, 0, wxT(""));
+          sprintf(dummy, "%d", pS->GetSrid());
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetCellValue(count, 1, cell);
+          GridCtrl->SetCellAlignment(count, 1, wxALIGN_RIGHT, wxALIGN_CENTRE);
+          GridCtrl->SetCellValue(count, 2, pS->GetAuthName());
+          sprintf(dummy, "%d", pS->GetAuthSrid());
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetCellValue(count, 3, cell);
+          GridCtrl->SetCellAlignment(count, 3, wxALIGN_RIGHT, wxALIGN_CENTRE);
+          GridCtrl->SetCellValue(count, 4, pS->GetRefSysName());
+          count++;
+          pS = pS->GetNext();
+        }
+      GridCtrl->AutoSizeColumns();
+    }
+  return;
+}
+
+void VectorSRIDsDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+VectorCoverageSRIDsList::~VectorCoverageSRIDsList()
+{
+// destructor
+  VectorCoverageSRID *pS;
+  VectorCoverageSRID *pSn;
+  pS = First;
+  while (pS != NULL)
+    {
+      pSn = pS->GetNext();
+      delete pS;
+      pS = pSn;
+    }
+}
+
+void VectorCoverageSRIDsList::Add(bool native, int srid, wxString & auth_name,
+                                  int auth_srid, wxString & name)
+{
+// inserting a new SRID
+  VectorCoverageSRID *pS =
+    new VectorCoverageSRID(native, srid, auth_name, auth_srid, name);
+  if (First == NULL)
+    First = pS;
+  if (Last != NULL)
+    Last->SetNext(pS);
+  Last = pS;
+}
+
+void VectorCoverageSRIDsList::MarkDeleted(int srid)
+{
+// marking some Srid as deleted
+  VectorCoverageSRID *pS;
+  pS = First;
+  while (pS != NULL)
+    {
+      if (pS->GetSrid() == srid)
+        {
+          pS->MarkDeleted();
+          return;
+        }
+      pS = pS->GetNext();
+    }
+}
+
+bool VectorCoverageSRIDsList::IsNativeSrid(int srid)
+{
+// checking for the Native SRID
+  VectorCoverageSRID *pS;
+  pS = First;
+  while (pS != NULL)
+    {
+      if (pS->GetSrid() == srid)
+        return pS->IsNative();
+      pS = pS->GetNext();
+    }
+  return false;
+}
+
+bool VectorCoverageSRIDsList::IsAlreadyDefinedSrid(int srid)
+{
+// checking for an already defined alternative SRID
+  VectorCoverageSRID *pS;
+  pS = First;
+  while (pS != NULL)
+    {
+      if (pS->GetSrid() == srid)
+        {
+          if (pS->IsDeleted() == true)
+            return false;
+          return true;
+        }
+      pS = pS->GetNext();
+    }
+  return false;
+}
+
+VectorCoverageSRIDsList *MyFrame::FindVectorAlternativeSRIDs(wxString &
+                                                             coverage)
+{
+// will retrieve all alternative SRIDs for the given Coverage
+  VectorCoverageSRIDsList *list = new VectorCoverageSRIDsList();
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  char *value;
+  char *sql;
+  char cvg[1024];
+
+  sprintf(cvg, coverage.ToUTF8());
+  sql =
+    sqlite3_mprintf
+    ("SELECT 1, s.srid, s.auth_name, s.auth_srid, s.ref_sys_name FROM vector_coverages AS v "
+     "JOIN geometry_columns AS x ON (v.f_table_name = x.f_table_name AND v.f_geometry_column = x.f_geometry_column) "
+     "LEFT JOIN spatial_ref_sys AS s ON (x.srid = s.srid) "
+     "WHERE v.coverage_name = %Q UNION "
+     "SELECT 0, s.srid, s.auth_name, s.auth_srid, s.ref_sys_name FROM vector_coverages AS v "
+     "JOIN vector_coverages_srid AS x ON (v.coverage_name = x.coverage_name) "
+     "LEFT JOIN spatial_ref_sys AS s ON (x.srid = s.srid) "
+     "WHERE v.coverage_name = %Q ORDER BY 2", cvg, cvg);
+  int ret = sqlite3_get_table(SqliteHandle, sql, &results,
+                              &rows, &columns, &errMsg);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return list;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          bool native = false;
+          value = results[(i * columns) + 0];
+          if (atoi(value) != 0)
+            native = true;
+          value = results[(i * columns) + 1];
+          int srid = atoi(value);
+          value = results[(i * columns) + 2];
+          wxString auth_name = wxString::FromUTF8(value);
+          value = results[(i * columns) + 3];
+          int auth_srid = atoi(value);
+          value = results[(i * columns) + 4];
+          wxString name = wxString::FromUTF8(value);
+          list->Add(native, srid, auth_name, auth_srid, name);
+        }
+    }
+  sqlite3_free_table(results);
+  return list;
+}
+
+bool VectorKeywordsDialog::Create(MyFrame * parent, wxString & coverage)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  int pos = coverage.Find(wxT(" [SRID="));
+  if (pos != wxNOT_FOUND)
+    CoverageName = coverage.Left(pos);
+  else
+    CoverageName = coverage;
+  List = MainFrame->FindVectorKeywords(CoverageName);
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Vector Coverage: Keywords")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void VectorKeywordsDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Vector Coverage
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_CENTRE_VERTICAL | wxALL, 0);
+  wxStaticText *cvgLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Coverage Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, wxID_ANY, CoverageName,
+                                       wxDefaultPosition, wxSize(550, 22),
+                                       wxTE_READONLY);
+  cvgCtrl->Enable(false);
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered Keywords"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_VECTOR_KEYWORD_GRID, wxDefaultPosition,
+               wxSize(640, 200), wxALWAYS_SHOW_SB);
+  int count = 0;
+  VectorCoverageKeyword *pK = List->GetFirst();
+  while (pK)
+    {
+      // counting how many lines are there
+      count++;
+      pK = pK->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 1, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Keyword"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pK = List->GetFirst();
+  while (pK)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%d", count + 1);
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetRowLabelValue(count, cell);
+      GridCtrl->SetCellValue(count, 0, pK->GetKeyword());
+      count++;
+      pK = pK->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// Keyword selection
+  wxBoxSizer *keywordBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(keywordBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *keywordBox = new wxStaticBox(this, wxID_STATIC,
+                                            wxT("Adding a Keyword"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *KeywordSizer = new wxStaticBoxSizer(keywordBox, wxHORIZONTAL);
+  keywordBoxSizer->Add(KeywordSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *keywordSizer = new wxBoxSizer(wxHORIZONTAL);
+  KeywordSizer->Add(keywordSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *keywordLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Keyword:"));
+  keywordSizer->Add(keywordLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *keywordCtrl = new wxTextCtrl(this, ID_VECTOR_KEYWORD, Keyword,
+                                           wxDefaultPosition, wxSize(400, 22));
+  keywordSizer->Add(keywordCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  keywordSizer->AddSpacer(100);
+  wxButton *addNew =
+    new wxButton(this, ID_VECTOR_KEYWORD_ADD, wxT("&Add Keyword"));
+  keywordSizer->Add(addNew, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & VectorKeywordsDialog::OnQuit);
+  Connect(ID_VECTOR_KEYWORD_ADD, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & VectorKeywordsDialog::OnCmdAddKeyword);
+  Connect(ID_VECTOR_KEYWORD_REMOVE, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & VectorKeywordsDialog::OnCmdRemoveKeyword);
+  Connect(wxID_ANY, wxEVT_GRID_CELL_RIGHT_CLICK,
+          (wxObjectEventFunction) & VectorKeywordsDialog::OnRightClick);
+}
+
+void VectorKeywordsDialog::OnRightClick(wxGridEvent & event)
+{
+//
+// right click on some cell [mouse action]
+//
+  wxMenu menu;
+  wxMenuItem *menuItem;
+  wxPoint pt = event.GetPosition();
+  CurrentRow = event.GetRow();
+  GridCtrl->SelectRow(CurrentRow);
+  Keyword = GridCtrl->GetCellValue(CurrentRow, 0);
+  menuItem = new wxMenuItem(&menu, ID_VECTOR_KEYWORD_REMOVE, wxT("&Remove"));
+  menu.Append(menuItem);
+  GridCtrl->PopupMenu(&menu, pt);
+}
+
+void VectorKeywordsDialog::OnCmdRemoveKeyword(wxCommandEvent & WXUNUSED(event))
+{
+//
+// deleting a Keyword [mouse action]
+//
+  sqlite3_stmt *stmt = NULL;
+  const char *sql = "SELECT SE_UnRegisterVectorCoverageKeyword(?, ?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 2, Keyword.ToUTF8(), -1, SQLITE_TRANSIENT);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+    {
+      GridCtrl->DeleteRows(CurrentRow, 1);
+      List->MarkDeleted(Keyword);
+    }
+  sqlite3_finalize(stmt);
+}
+
+bool VectorKeywordsDialog::DoRegistetVectorCoverageKeyword(wxString & keyword)
+{
+//
+// attempting to register a Vector Coverage Keyword
+//
+  sqlite3_stmt *stmt = NULL;
+  int value = 0;
+  const char *sql = "SELECT SE_RegisterVectorCoverageKeyword(?, ?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 2, keyword.ToUTF8(), -1, SQLITE_TRANSIENT);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE)
+    ;
+  else if (ret == SQLITE_ROW)
+    value = sqlite3_column_int(stmt, 0);
+  else
+    {
+      sqlite3_finalize(stmt);
+      return false;
+    }
+  sqlite3_finalize(stmt);
+  if (!value)
+    return false;
+  return true;
+}
+
+void VectorKeywordsDialog::OnCmdAddKeyword(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxTextCtrl *keywordCtrl = (wxTextCtrl *) FindWindow(ID_VECTOR_KEYWORD);
+  wxString keyword = keywordCtrl->GetValue();
+  if (keyword.Len() <= 0)
+    {
+      wxMessageBox(wxT("You must specify some Keyword !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (List->IsAlreadyDefinedKeyword(keyword) == true)
+    {
+      wxMessageBox(wxT("Already defined Keyword"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  // attempting to register the Keyword
+  if (DoRegistetVectorCoverageKeyword(keyword) == true)
+    {
+      // updating the Grid
+      int tot_rows = GridCtrl->GetNumberRows();
+      GridCtrl->DeleteRows(0, tot_rows);
+      if (List != NULL)
+        delete List;
+      List = MainFrame->FindVectorKeywords(CoverageName);
+      int count = 0;
+      VectorCoverageKeyword *pK = List->GetFirst();
+      while (pK)
+        {
+          // counting how many lines are there
+          count++;
+          pK = pK->GetNext();
+        }
+      GridCtrl->AppendRows(count);
+      count = 0;
+      char dummy[1024];
+      wxString cell;
+      pK = List->GetFirst();
+      while (pK)
+        {
+          // feeding grid rows
+          sprintf(dummy, "%d", count + 1);
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetRowLabelValue(count, cell);
+          GridCtrl->SetCellValue(count, 0, pK->GetKeyword());
+          count++;
+          pK = pK->GetNext();
+        }
+      GridCtrl->AutoSizeColumns();
+    }
+  return;
+}
+
+void VectorKeywordsDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+VectorCoverageKeywordsList::~VectorCoverageKeywordsList()
+{
+// destructor
+  VectorCoverageKeyword *pK;
+  VectorCoverageKeyword *pKn;
+  pK = First;
+  while (pK != NULL)
+    {
+      pKn = pK->GetNext();
+      delete pK;
+      pK = pKn;
+    }
+}
+
+void VectorCoverageKeywordsList::Add(wxString & keyword)
+{
+// inserting a new Keyword
+  VectorCoverageKeyword *pK = new VectorCoverageKeyword(keyword);
+  if (First == NULL)
+    First = pK;
+  if (Last != NULL)
+    Last->SetNext(pK);
+  Last = pK;
+}
+
+void VectorCoverageKeywordsList::MarkDeleted(wxString & keyword)
+{
+// marking some Keyword as deleted
+  VectorCoverageKeyword *pK;
+  pK = First;
+  while (pK != NULL)
+    {
+      if (pK->GetKeyword().CmpNoCase(keyword) == 0)
+        {
+          pK->MarkDeleted();
+          return;
+        }
+      pK = pK->GetNext();
+    }
+}
+
+bool VectorCoverageKeywordsList::IsAlreadyDefinedKeyword(wxString & keyword)
+{
+// checking for an already defined Keyword
+  VectorCoverageKeyword *pK;
+  pK = First;
+  while (pK != NULL)
+    {
+      if (pK->GetKeyword().CmpNoCase(keyword) == 0)
+        {
+          if (pK->IsDeleted() == true)
+            return false;
+          return true;
+        }
+      pK = pK->GetNext();
+    }
+  return false;
+}
+
+VectorCoverageKeywordsList *MyFrame::FindVectorKeywords(wxString & coverage)
+{
+// will retrieve all Keywords for the given Coverage
+  VectorCoverageKeywordsList *list = new VectorCoverageKeywordsList();
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  char *value;
+  char *sql;
+  char cvg[1024];
+
+  sprintf(cvg, coverage.ToUTF8());
+  sql =
+    sqlite3_mprintf
+    ("SELECT keyword FROM vector_coverages_keyword WHERE coverage_name = %Q ORDER BY 1",
+     cvg);
+  int ret = sqlite3_get_table(SqliteHandle, sql, &results,
+                              &rows, &columns, &errMsg);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return list;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          value = results[(i * columns) + 0];
+          wxString keyword = wxString::FromUTF8(value);
+          list->Add(keyword);
+        }
+    }
+  sqlite3_free_table(results);
+  return list;
+}
+
+bool RasterSRIDsDialog::Create(MyFrame * parent, wxString & coverage)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  int pos = coverage.Find(wxT(" [SRID="));
+  if (pos != wxNOT_FOUND)
+    CoverageName = coverage.Left(pos);
+  else
+    CoverageName = coverage;
+  List = MainFrame->FindRasterAlternativeSRIDs(CoverageName);
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Raster Coverage: alternative SRIDs")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void RasterSRIDsDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Raster Coverage
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_CENTRE_VERTICAL | wxALL, 0);
+  wxStaticText *cvgLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Coverage Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, wxID_ANY, CoverageName,
+                                       wxDefaultPosition, wxSize(550, 22),
+                                       wxTE_READONLY);
+  cvgCtrl->Enable(false);
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered alternative SRIDs"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_RASTER_SRID_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  RasterCoverageSRID *pS = List->GetFirst();
+  while (pS)
+    {
+      // counting how many lines are there
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 5, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Native"));
+  GridCtrl->SetColLabelValue(1, wxT("SRID"));
+  GridCtrl->SetColLabelValue(2, wxT("Auth Name"));
+  GridCtrl->SetColLabelValue(3, wxT("Auth SRID"));
+  GridCtrl->SetColLabelValue(4, wxT("RefSys Name"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pS = List->GetFirst();
+  while (pS)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%d", count + 1);
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetRowLabelValue(count, cell);
+      if (pS->IsNative() == true)
+        GridCtrl->SetCellValue(count, 0, wxT("yes"));
+      else
+        GridCtrl->SetCellValue(count, 0, wxT(""));
+      sprintf(dummy, "%d", pS->GetSrid());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 1, cell);
+      GridCtrl->SetCellAlignment(count, 1, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 2, pS->GetAuthName());
+      sprintf(dummy, "%d", pS->GetAuthSrid());
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetCellValue(count, 3, cell);
+      GridCtrl->SetCellAlignment(count, 3, wxALIGN_RIGHT, wxALIGN_CENTRE);
+      GridCtrl->SetCellValue(count, 4, pS->GetRefSysName());
+      count++;
+      pS = pS->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// SRID selection
+  wxBoxSizer *sridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(sridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *sridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Adding an alternative SRID"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *SridSizer = new wxStaticBoxSizer(sridBox, wxHORIZONTAL);
+  sridBoxSizer->Add(SridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *sridSizer = new wxBoxSizer(wxHORIZONTAL);
+  SridSizer->Add(sridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *sridLabel = new wxStaticText(this, wxID_STATIC, wxT("&SRID:"));
+  sridSizer->Add(sridLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  int srid = 0;
+  wxSpinCtrl *sridCtrl = new wxSpinCtrl(this, ID_RASTER_SRID, wxEmptyString,
+                                        wxDefaultPosition, wxSize(80, 20),
+                                        wxSP_ARROW_KEYS,
+                                        -1, 1000000, srid);
+  sridSizer->Add(sridCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  sridSizer->AddSpacer(100);
+  wxButton *addNew = new wxButton(this, ID_RASTER_SRID_ADD, wxT("&Add SRID"));
+  sridSizer->Add(addNew, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSRIDsDialog::OnQuit);
+  Connect(ID_RASTER_SRID_ADD, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterSRIDsDialog::OnCmdAddSrid);
+  Connect(ID_RASTER_SRID_REMOVE, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & RasterSRIDsDialog::OnCmdRemoveSrid);
+  Connect(wxID_ANY, wxEVT_GRID_CELL_RIGHT_CLICK,
+          (wxObjectEventFunction) & RasterSRIDsDialog::OnRightClick);
+}
+
+void RasterSRIDsDialog::OnRightClick(wxGridEvent & event)
+{
+//
+// right click on some cell [mouse action]
+//
+  wxMenu menu;
+  wxMenuItem *menuItem;
+  wxPoint pt = event.GetPosition();
+  CurrentRow = event.GetRow();
+  GridCtrl->SelectRow(CurrentRow);
+  wxString native = GridCtrl->GetCellValue(CurrentRow, 0);
+  if (native.CmpNoCase(wxT("yes")) == 0)
+    return;
+  wxString id = GridCtrl->GetCellValue(CurrentRow, 1);
+  long srid;
+  id.ToLong(&srid);
+  CurrentSRID = srid;
+  menuItem = new wxMenuItem(&menu, ID_RASTER_SRID_REMOVE, wxT("&Remove"));
+  menu.Append(menuItem);
+  GridCtrl->PopupMenu(&menu, pt);
+}
+
+void RasterSRIDsDialog::OnCmdRemoveSrid(wxCommandEvent & WXUNUSED(event))
+{
+//
+// deleting a SRID [mouse action]
+//
+  sqlite3_stmt *stmt = NULL;
+  const char *sql = "SELECT SE_UnRegisterRasterCoverageSrid(?, ?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_int(stmt, 2, CurrentSRID);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+    {
+      GridCtrl->DeleteRows(CurrentRow, 1);
+      List->MarkDeleted(CurrentSRID);
+    }
+  sqlite3_finalize(stmt);
+}
+
+bool RasterSRIDsDialog::DoRegistetRasterCoverageSrid(int srid)
+{
+//
+// attempting to register an alternative Raster Coverage SRID
+//
+  sqlite3_stmt *stmt = NULL;
+  int value = 0;
+  const char *sql = "SELECT SE_RegisterRasterCoverageSrid(?, ?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_int(stmt, 2, srid);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE)
+    ;
+  else if (ret == SQLITE_ROW)
+    value = sqlite3_column_int(stmt, 0);
+  else
+    {
+      sqlite3_finalize(stmt);
+      return false;
+    }
+  sqlite3_finalize(stmt);
+  if (!value)
+    return false;
+  return true;
+}
+
+void RasterSRIDsDialog::OnCmdAddSrid(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxSpinCtrl *sridCtrl = (wxSpinCtrl *) FindWindow(ID_RASTER_SRID);
+  int srid = sridCtrl->GetValue();
+  if (srid <= 0)
+    {
+      wxMessageBox(wxT("You must specify some SRID value !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+  } else if (MainFrame->SridNotExists(srid) == true)
+    {
+      wxMessageBox(wxT("invalid SRID value"), wxT("spatialite_gui"),
+                   wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (List->IsNativeSrid(srid) == true)
+    {
+      wxMessageBox(wxT("Can't register twice the Native SRID"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (List->IsAlreadyDefinedSrid(srid) == true)
+    {
+      wxMessageBox(wxT("Already defined alternative SRID"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  // attempting to register the alternative SRID
+  if (DoRegistetRasterCoverageSrid(srid) == true)
+    {
+      // updating the Grid
+      int tot_rows = GridCtrl->GetNumberRows();
+      GridCtrl->DeleteRows(0, tot_rows);
+      if (List != NULL)
+        delete List;
+      List = MainFrame->FindRasterAlternativeSRIDs(CoverageName);
+      int count = 0;
+      RasterCoverageSRID *pS = List->GetFirst();
+      while (pS)
+        {
+          // counting how many lines are there
+          count++;
+          pS = pS->GetNext();
+        }
+      GridCtrl->AppendRows(count);
+      count = 0;
+      char dummy[1024];
+      wxString cell;
+      pS = List->GetFirst();
+      while (pS)
+        {
+          // feeding grid rows
+          sprintf(dummy, "%d", count + 1);
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetRowLabelValue(count, cell);
+          if (pS->IsNative() == true)
+            GridCtrl->SetCellValue(count, 0, wxT("yes"));
+          else
+            GridCtrl->SetCellValue(count, 0, wxT(""));
+          sprintf(dummy, "%d", pS->GetSrid());
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetCellValue(count, 1, cell);
+          GridCtrl->SetCellAlignment(count, 1, wxALIGN_RIGHT, wxALIGN_CENTRE);
+          GridCtrl->SetCellValue(count, 2, pS->GetAuthName());
+          sprintf(dummy, "%d", pS->GetAuthSrid());
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetCellValue(count, 3, cell);
+          GridCtrl->SetCellAlignment(count, 3, wxALIGN_RIGHT, wxALIGN_CENTRE);
+          GridCtrl->SetCellValue(count, 4, pS->GetRefSysName());
+          count++;
+          pS = pS->GetNext();
+        }
+      GridCtrl->AutoSizeColumns();
+    }
+  return;
+}
+
+void RasterSRIDsDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+RasterCoverageSRIDsList::~RasterCoverageSRIDsList()
+{
+// destructor
+  RasterCoverageSRID *pS;
+  RasterCoverageSRID *pSn;
+  pS = First;
+  while (pS != NULL)
+    {
+      pSn = pS->GetNext();
+      delete pS;
+      pS = pSn;
+    }
+}
+
+void RasterCoverageSRIDsList::Add(bool native, int srid, wxString & auth_name,
+                                  int auth_srid, wxString & name)
+{
+// inserting a new SRID
+  RasterCoverageSRID *pS =
+    new RasterCoverageSRID(native, srid, auth_name, auth_srid, name);
+  if (First == NULL)
+    First = pS;
+  if (Last != NULL)
+    Last->SetNext(pS);
+  Last = pS;
+}
+
+void RasterCoverageSRIDsList::MarkDeleted(int srid)
+{
+// marking some Srid as deleted
+  RasterCoverageSRID *pS;
+  pS = First;
+  while (pS != NULL)
+    {
+      if (pS->GetSrid() == srid)
+        {
+          pS->MarkDeleted();
+          return;
+        }
+      pS = pS->GetNext();
+    }
+}
+
+bool RasterCoverageSRIDsList::IsNativeSrid(int srid)
+{
+// checking for the Native SRID
+  RasterCoverageSRID *pS;
+  pS = First;
+  while (pS != NULL)
+    {
+      if (pS->GetSrid() == srid)
+        return pS->IsNative();
+      pS = pS->GetNext();
+    }
+  return false;
+}
+
+bool RasterCoverageSRIDsList::IsAlreadyDefinedSrid(int srid)
+{
+// checking for an already defined alternative SRID
+  RasterCoverageSRID *pS;
+  pS = First;
+  while (pS != NULL)
+    {
+      if (pS->GetSrid() == srid)
+        {
+          if (pS->IsDeleted() == true)
+            return false;
+          return true;
+        }
+      pS = pS->GetNext();
+    }
+  return false;
+}
+
+RasterCoverageSRIDsList *MyFrame::FindRasterAlternativeSRIDs(wxString &
+                                                             coverage)
+{
+// will retrieve all alternative SRIDs for the given Coverage
+  RasterCoverageSRIDsList *list = new RasterCoverageSRIDsList();
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  char *value;
+  char *sql;
+  char cvg[1024];
+
+  sprintf(cvg, coverage.ToUTF8());
+  sql =
+    sqlite3_mprintf
+    ("SELECT 1, s.srid, s.auth_name, s.auth_srid, s.ref_sys_name FROM raster_coverages AS v "
+     "LEFT JOIN spatial_ref_sys AS s ON (v.srid = s.srid) "
+     "WHERE v.coverage_name = %Q UNION "
+     "SELECT 0, s.srid, s.auth_name, s.auth_srid, s.ref_sys_name FROM raster_coverages AS v "
+     "JOIN raster_coverages_srid AS x ON (v.coverage_name = x.coverage_name) "
+     "LEFT JOIN spatial_ref_sys AS s ON (x.srid = s.srid) "
+     "WHERE v.coverage_name = %Q ORDER BY 2", cvg, cvg);
+  int ret = sqlite3_get_table(SqliteHandle, sql, &results,
+                              &rows, &columns, &errMsg);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return list;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          bool native = false;
+          value = results[(i * columns) + 0];
+          if (atoi(value) != 0)
+            native = true;
+          value = results[(i * columns) + 1];
+          int srid = atoi(value);
+          value = results[(i * columns) + 2];
+          wxString auth_name = wxString::FromUTF8(value);
+          value = results[(i * columns) + 3];
+          int auth_srid = atoi(value);
+          value = results[(i * columns) + 4];
+          wxString name = wxString::FromUTF8(value);
+          list->Add(native, srid, auth_name, auth_srid, name);
+        }
+    }
+  sqlite3_free_table(results);
+  return list;
+}
+
+bool RasterKeywordsDialog::Create(MyFrame * parent, wxString & coverage)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  int pos = coverage.Find(wxT(" [SRID="));
+  if (pos != wxNOT_FOUND)
+    CoverageName = coverage.Left(pos);
+  else
+    CoverageName = coverage;
+  List = MainFrame->FindRasterKeywords(CoverageName);
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Raster Coverage: Keywords")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void RasterKeywordsDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: the Raster Coverage
+  wxBoxSizer *cvgSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(cvgSizer, 0, wxALIGN_CENTRE_VERTICAL | wxALL, 0);
+  wxStaticText *cvgLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Coverage Name:"));
+  cvgSizer->Add(cvgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *cvgCtrl = new wxTextCtrl(this, wxID_ANY, CoverageName,
+                                       wxDefaultPosition, wxSize(550, 22),
+                                       wxTE_READONLY);
+  cvgCtrl->Enable(false);
+  cvgSizer->Add(cvgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered Keywords"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_RASTER_KEYWORD_GRID, wxDefaultPosition,
+               wxSize(640, 200), wxALWAYS_SHOW_SB);
+  int count = 0;
+  RasterCoverageKeyword *pK = List->GetFirst();
+  while (pK)
+    {
+      // counting how many lines are there
+      count++;
+      pK = pK->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 1, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Keyword"));
+  GridCtrl->SetRowLabelValue(0, wxT("1"));
+  count = 0;
+  char dummy[1024];
+  wxString cell;
+  pK = List->GetFirst();
+  while (pK)
+    {
+      // feeding grid rows
+      sprintf(dummy, "%d", count + 1);
+      cell = wxString::FromUTF8(dummy);
+      GridCtrl->SetRowLabelValue(count, cell);
+      GridCtrl->SetCellValue(count, 0, pK->GetKeyword());
+      count++;
+      pK = pK->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// Keyword selection
+  wxBoxSizer *keywordBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(keywordBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *keywordBox = new wxStaticBox(this, wxID_STATIC,
+                                            wxT("Adding a Keyword"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *KeywordSizer = new wxStaticBoxSizer(keywordBox, wxHORIZONTAL);
+  keywordBoxSizer->Add(KeywordSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *keywordSizer = new wxBoxSizer(wxHORIZONTAL);
+  KeywordSizer->Add(keywordSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *keywordLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("&Keyword:"));
+  keywordSizer->Add(keywordLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *keywordCtrl = new wxTextCtrl(this, ID_RASTER_KEYWORD, Keyword,
+                                           wxDefaultPosition, wxSize(400, 22));
+  keywordSizer->Add(keywordCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  keywordSizer->AddSpacer(100);
+  wxButton *addNew =
+    new wxButton(this, ID_RASTER_KEYWORD_ADD, wxT("&Add Keyword"));
+  keywordSizer->Add(addNew, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterKeywordsDialog::OnQuit);
+  Connect(ID_RASTER_KEYWORD_ADD, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & RasterKeywordsDialog::OnCmdAddKeyword);
+  Connect(ID_RASTER_KEYWORD_REMOVE, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & RasterKeywordsDialog::OnCmdRemoveKeyword);
+  Connect(wxID_ANY, wxEVT_GRID_CELL_RIGHT_CLICK,
+          (wxObjectEventFunction) & RasterKeywordsDialog::OnRightClick);
+}
+
+void RasterKeywordsDialog::OnRightClick(wxGridEvent & event)
+{
+//
+// right click on some cell [mouse action]
+//
+  wxMenu menu;
+  wxMenuItem *menuItem;
+  wxPoint pt = event.GetPosition();
+  CurrentRow = event.GetRow();
+  GridCtrl->SelectRow(CurrentRow);
+  Keyword = GridCtrl->GetCellValue(CurrentRow, 0);
+  menuItem = new wxMenuItem(&menu, ID_RASTER_KEYWORD_REMOVE, wxT("&Remove"));
+  menu.Append(menuItem);
+  GridCtrl->PopupMenu(&menu, pt);
+}
+
+void RasterKeywordsDialog::OnCmdRemoveKeyword(wxCommandEvent & WXUNUSED(event))
+{
+//
+// deleting a Keyword [mouse action]
+//
+  sqlite3_stmt *stmt = NULL;
+  const char *sql = "SELECT SE_UnRegisterRasterCoverageKeyword(?, ?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 2, Keyword.ToUTF8(), -1, SQLITE_TRANSIENT);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+    {
+      GridCtrl->DeleteRows(CurrentRow, 1);
+      List->MarkDeleted(Keyword);
+    }
+  sqlite3_finalize(stmt);
+}
+
+bool RasterKeywordsDialog::DoRegistetRasterCoverageKeyword(wxString & keyword)
+{
+//
+// attempting to register a Raster Coverage Keyword
+//
+  sqlite3_stmt *stmt = NULL;
+  int value = 0;
+  const char *sql = "SELECT SE_RegisterRasterCoverageKeyword(?, ?)";
+  int ret = sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, CoverageName.ToUTF8(), -1, SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 2, keyword.ToUTF8(), -1, SQLITE_TRANSIENT);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE)
+    ;
+  else if (ret == SQLITE_ROW)
+    value = sqlite3_column_int(stmt, 0);
+  else
+    {
+      sqlite3_finalize(stmt);
+      return false;
+    }
+  sqlite3_finalize(stmt);
+  if (!value)
+    return false;
+  return true;
+}
+
+void RasterKeywordsDialog::OnCmdAddKeyword(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxTextCtrl *keywordCtrl = (wxTextCtrl *) FindWindow(ID_RASTER_KEYWORD);
+  wxString keyword = keywordCtrl->GetValue();
+  if (keyword.Len() <= 0)
+    {
+      wxMessageBox(wxT("You must specify some Keyword !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (List->IsAlreadyDefinedKeyword(keyword) == true)
+    {
+      wxMessageBox(wxT("Already defined Keyword"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  // attempting to register the Keyword
+  if (DoRegistetRasterCoverageKeyword(keyword) == true)
+    {
+      // updating the Grid
+      int tot_rows = GridCtrl->GetNumberRows();
+      GridCtrl->DeleteRows(0, tot_rows);
+      if (List != NULL)
+        delete List;
+      List = MainFrame->FindRasterKeywords(CoverageName);
+      int count = 0;
+      RasterCoverageKeyword *pK = List->GetFirst();
+      while (pK)
+        {
+          // counting how many lines are there
+          count++;
+          pK = pK->GetNext();
+        }
+      GridCtrl->AppendRows(count);
+      count = 0;
+      char dummy[1024];
+      wxString cell;
+      pK = List->GetFirst();
+      while (pK)
+        {
+          // feeding grid rows
+          sprintf(dummy, "%d", count + 1);
+          cell = wxString::FromUTF8(dummy);
+          GridCtrl->SetRowLabelValue(count, cell);
+          GridCtrl->SetCellValue(count, 0, pK->GetKeyword());
+          count++;
+          pK = pK->GetNext();
+        }
+      GridCtrl->AutoSizeColumns();
+    }
+  return;
+}
+
+void RasterKeywordsDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+RasterCoverageKeywordsList::~RasterCoverageKeywordsList()
+{
+// destructor
+  RasterCoverageKeyword *pK;
+  RasterCoverageKeyword *pKn;
+  pK = First;
+  while (pK != NULL)
+    {
+      pKn = pK->GetNext();
+      delete pK;
+      pK = pKn;
+    }
+}
+
+void RasterCoverageKeywordsList::Add(wxString & keyword)
+{
+// inserting a new Keyword
+  RasterCoverageKeyword *pK = new RasterCoverageKeyword(keyword);
+  if (First == NULL)
+    First = pK;
+  if (Last != NULL)
+    Last->SetNext(pK);
+  Last = pK;
+}
+
+void RasterCoverageKeywordsList::MarkDeleted(wxString & keyword)
+{
+// marking some Keyword as deleted
+  RasterCoverageKeyword *pK;
+  pK = First;
+  while (pK != NULL)
+    {
+      if (pK->GetKeyword().CmpNoCase(keyword) == 0)
+        {
+          pK->MarkDeleted();
+          return;
+        }
+      pK = pK->GetNext();
+    }
+}
+
+bool RasterCoverageKeywordsList::IsAlreadyDefinedKeyword(wxString & keyword)
+{
+// checking for an already defined Keyword
+  RasterCoverageKeyword *pK;
+  pK = First;
+  while (pK != NULL)
+    {
+      if (pK->GetKeyword().CmpNoCase(keyword) == 0)
+        {
+          if (pK->IsDeleted() == true)
+            return false;
+          return true;
+        }
+      pK = pK->GetNext();
+    }
+  return false;
+}
+
+RasterCoverageKeywordsList *MyFrame::FindRasterKeywords(wxString & coverage)
+{
+// will retrieve all Keywords for the given Coverage
+  RasterCoverageKeywordsList *list = new RasterCoverageKeywordsList();
+  int i;
+  char **results;
+  int rows;
+  int columns;
+  char *errMsg = NULL;
+  char *value;
+  char *sql;
+  char cvg[1024];
+
+  sprintf(cvg, coverage.ToUTF8());
+  sql =
+    sqlite3_mprintf
+    ("SELECT keyword FROM raster_coverages_keyword WHERE coverage_name = %Q ORDER BY 1",
+     cvg);
+  int ret = sqlite3_get_table(SqliteHandle, sql, &results,
+                              &rows, &columns, &errMsg);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      return list;
+    }
+  if (rows < 1)
+    ;
+  else
+    {
+      for (i = 1; i <= rows; i++)
+        {
+          value = results[(i * columns) + 0];
+          wxString keyword = wxString::FromUTF8(value);
+          list->Add(keyword);
+        }
+    }
+  sqlite3_free_table(results);
+  return list;
+}
+
+bool LoadExternalGraphicDialog::Create(MyFrame * parent, wxArrayString & paths,
+                                       wxString & path)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Paths = paths;
+  Path = path;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Loading New External Graphic resource(s)")) ==
+      false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void LoadExternalGraphicDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: files to be imported
+  wxBoxSizer *fileSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(fileSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *fileLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("Import &File(s):"));
+  fileSizer->Add(fileLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *filesCtrl = new wxTextCtrl(this, wxID_ANY, Path,
+                                         wxDefaultPosition, wxSize(600, 60),
+                                         wxTE_MULTILINE | wxTE_READONLY);
+  fileSizer->Add(filesCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: progress report
+  wxBoxSizer *progrSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(progrSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *doneCtrl = new wxTextCtrl(this, ID_LOAD_EXTERNAL_DONE, ListDone,
+                                        wxDefaultPosition, wxSize(650, 100),
+                                        wxTE_MULTILINE | wxTE_READONLY |
+                                        wxTE_RICH2);
+  progrSizer->Add(doneCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+
+// OK - CANCEL buttons
+  wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Import"));
+  okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Quit"));
+  okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *abort = new wxButton(this, ID_LOAD_ABORT, wxT("&Abort"));
+  abort->Enable(false);
+  okCancelBox->Add(abort, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadExternalGraphicDialog::OnOk);
+  Connect(ID_LOAD_ABORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadExternalGraphicDialog::OnCmdAbort);
+  Connect(ID_LOAD_EXTERNAL_START, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadExternalGraphicDialog::OnRequestStart);
+  Connect(ID_LOAD_EXTERNAL_STOP, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadExternalGraphicDialog::OnRequestStop);
+  Connect(ID_LOAD_EXTERNAL_SKIP, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadExternalGraphicDialog::OnRequestSkip);
+  Connect(ID_LOAD_EXTERNAL_THREAD_FINISHED, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          LoadExternalGraphicDialog::OnThreadFinished);
+}
+
+void LoadExternalGraphicDialog::OnCmdAbort(wxCommandEvent & WXUNUSED(event))
+{
+//
+// aborting the External Graphic(s) Import process
+//
+  if (Params.IsAbortPending() == true)
+    return;
+  Params.RequestAbort();
+  wxString report =
+    wxT("\nan ABORT request is now pending and will be accepted ASAP");
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_EXTERNAL_DONE);
+  wxColour fore = wxColour(255, 255, 255);
+  wxColour back = wxColour(192, 0, 0);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(report);
+}
+
+void LoadExternalGraphicDialog::OnRequestStart(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_EXTERNAL_DONE);
+  wxColour fore = wxColour(255, 255, 255);
+  wxColour back = wxColour(0, 0, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(msg);
+  doneCtrl->MarkDirty();
+}
+
+void LoadExternalGraphicDialog::OnRequestStop(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_EXTERNAL_DONE);
+  ListDone += msg;
+  doneCtrl->Clear();
+  wxColour fore = wxColour(0, 0, 0);
+  wxColour back = wxColour(255, 255, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(ListDone);
+  doneCtrl->MarkDirty();
+}
+
+void LoadExternalGraphicDialog::OnRequestSkip(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_EXTERNAL_DONE);
+  ListDone += msg;
+  doneCtrl->Clear();
+  wxColour fore = wxColour(0, 0, 0);
+  wxColour back = wxColour(255, 0, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(ListDone);
+  doneCtrl->MarkDirty();
+}
+
+#ifdef _WIN32
+DWORD WINAPI DoExecuteExternalGraphicLoad(void *arg)
+#else
+void *DoExecuteExternalGraphicLoad(void *arg)
+#endif
+{
+//
+// threaded function: processing an External Graphic Import operation
+//
+  ExternalGraphicLoadParams *params = (ExternalGraphicLoadParams *) arg;
+  const char *sql;
+  int ret;
+  sqlite3_stmt *stmt = NULL;
+  int count = params->GetPathsCount();
+  int i;
+  clock_t clock_start;
+  clock_t clock_end;
+  double seconds;
+  char elapsed[64];
+  char ordinal[64];
+  wxString report;
+  wxString path;
+  void *blob;
+  int blob_size;
+  wxCommandEvent evt_start(wxEVT_COMMAND_BUTTON_CLICKED,
+                           ID_LOAD_EXTERNAL_START);
+  wxCommandEvent evt_stop(wxEVT_COMMAND_BUTTON_CLICKED, ID_LOAD_EXTERNAL_STOP);
+  wxCommandEvent evt_skip(wxEVT_COMMAND_BUTTON_CLICKED, ID_LOAD_EXTERNAL_SKIP);
+
+  sql = "SELECT SE_RegisterExternalGraphic(?, ?, ?, ?, ?)";
+  ret =
+    sqlite3_prepare_v2(params->GetMainFrame()->GetSqlite(), sql, strlen(sql),
+                       &stmt, NULL);
+  if (ret != SQLITE_OK)
+    {
+      params->SetError();
+      goto error;
+    }
+
+  for (i = 0; i < count; i++)
+    {
+      // loading and verifying each External Graphic resource
+      if (params->IsAbortPending() == true)
+        {
+          report = wxT("STOP .... aborted by the user !!!!");
+          evt_start.SetString(report);
+          params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_start);
+          break;
+        }
+      path = params->GetPathByIndex(i);
+      params->SetCurrentPath(path);
+      report = wxT("Loading and Validating: ") + path;
+      evt_start.SetString(report);
+      params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_start);
+      clock_start = clock();
+      wxString abstract;
+      if (params->
+          GetMainFrame()->ValidateExternalGraphicResource(path.ToUTF8(), &blob,
+                                                          &blob_size,
+                                                          abstract) == true)
+        {
+          wxFileName fn(path);
+          wxString xlink_href =
+            wxT("http://www.utopia.gov/") + fn.GetFullName();
+          wxString filename = fn.GetFullName();
+          wxString title = fn.GetName();
+          if (params->
+              GetDlg()->RegisterExternalGraphic(stmt, xlink_href.ToUTF8(),
+                                                title.ToUTF8(),
+                                                abstract.ToUTF8(),
+                                                filename.ToUTF8(), blob,
+                                                blob_size) != true)
+            {
+              params->SetError();
+              goto error;
+            }
+          clock_end = clock();
+          seconds =
+            (double) (clock_end - clock_start) / (double) CLOCKS_PER_SEC;
+          MyResultSetView::FormatElapsedTime(seconds, elapsed);
+          sprintf(ordinal, "done %d/%d: ", i + 1, count);
+          report =
+            wxString::FromUTF8(ordinal) + path + wxT("    [") +
+            wxString::FromUTF8(elapsed) + wxT("]\n");
+          evt_stop.SetString(report);
+          params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_stop);
+          params->Done();
+      } else
+        {
+          clock_end = clock();
+          seconds =
+            (double) (clock_end - clock_start) / (double) CLOCKS_PER_SEC;
+          MyResultSetView::FormatElapsedTime(seconds, elapsed);
+          sprintf(ordinal, "discarded %d/%d (not a valid External Graphic): ",
+                  i + 1, count);
+          report =
+            wxString::FromUTF8(ordinal) + path + wxT("    [") +
+            wxString::FromUTF8(elapsed) + wxT("]\n");
+          evt_skip.SetString(report);
+          params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_skip);
+        }
+    }
+  sqlite3_finalize(stmt);
+  goto end;
+
+error:
+  sqlite3_finalize(stmt);
+  report = wxT("FAILED: ") + path;
+  evt_stop.SetString(report);
+  params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_stop);
+  params->SetError();
+end:
+  wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED,
+                       ID_LOAD_EXTERNAL_THREAD_FINISHED);
+  params->GetDlg()->GetEventHandler()->AddPendingEvent(event);
+#ifdef _WIN32
+  return 0;
+#else
+  pthread_exit(NULL);
+#endif
+}
+
+void LoadExternalGraphicDialog::
+OnThreadFinished(wxCommandEvent & WXUNUSED(event))
+{
+// resuming execution when the Import External Graphic thread quits
+  ::wxEndBusyCursor();
+  wxButton *quitBtn = (wxButton *) FindWindow(wxID_CANCEL);
+  wxButton *abortBtn = (wxButton *) FindWindow(ID_LOAD_ABORT);
+  quitBtn->Enable(true);
+  abortBtn->Enable(false);
+  sqlite3_exec(Params.GetMainFrame()->GetSqlite(), "COMMIT", NULL, NULL, NULL);
+  if (Params.GetError() == true)
+    {
+      char dummy[80];
+      sprintf(dummy,
+              "%d External Graphic resources have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy) +
+                   wxT("\n\nA fatal error occurred while loading:\n") +
+                   Params.GetCurrentPath(), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+  } else if (Params.IsAbortPending() == true)
+    {
+      char dummy[80];
+      sprintf(dummy,
+              "%d External Graphic resources have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy) +
+                   wxT("\n\nStopped by an Abort user request"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+  } else
+    {
+      char dummy[80];
+      sprintf(dummy,
+              "%d External Graphic resources have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy), wxT("spatialite_gui"),
+                   wxOK | wxICON_INFORMATION, this);
+    }
+}
+
+bool MyFrame::ValidateExternalGraphicResource(const char *path, void **blob,
+                                              int *blob_size,
+                                              wxString & abstract)
+{
+//
+// attempting to load and validate an External Graphic
+//
+  int ret;
+  sqlite3_stmt *stmt;
+  void *xblob = NULL;
+  int xblob_size;
+  int valid = 0;
+
+// Loading from file - testing for an eventual SVG image
+  char *sql = sqlite3_mprintf("SELECT XB_Create(BlobFromFile(%Q), 1)", path);
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    return false;
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_BLOB)
+            {
+              const void *xxblob = sqlite3_column_blob(stmt, 0);
+              xblob_size = sqlite3_column_bytes(stmt, 0);
+              xblob = malloc(xblob_size);
+              memcpy(xblob, xxblob, xblob_size);
+            }
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (xblob != NULL)
+    goto ok_svg;
+// Loading from file - testing for an eventual SVG image
+  sql = sqlite3_mprintf("SELECT BlobFromFile(%Q)", path);
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    return false;
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_BLOB)
+            {
+              const void *xxblob = sqlite3_column_blob(stmt, 0);
+              xblob_size = sqlite3_column_bytes(stmt, 0);
+              xblob = malloc(xblob_size);
+              memcpy(xblob, xxblob, xblob_size);
+            }
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (xblob == NULL)
+    return false;
+ok_svg:
+
+// Checking if really is a valid External Graphic resource
+  stmt = NULL;
+  sql = sqlite3_mprintf("SELECT GetMimeType(?)");
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  sqlite3_free(sql);
+  if (ret != SQLITE_OK)
+    goto invalid;
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_blob(stmt, 1, xblob, xblob_size, SQLITE_STATIC);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_TEXT)
+            {
+              rl2RasterPtr raster;
+              unsigned int width;
+              unsigned int height;
+              char dummy[128];
+              const char *mime_type =
+                (const char *) sqlite3_column_text(stmt, 0);
+              if (strcmp(mime_type, "image/gif") == 0)
+                {
+                  abstract = wxT("GIF icon: ");
+                  raster =
+                    rl2_raster_from_gif((const unsigned char *) xblob,
+                                        xblob_size);
+                  if (raster != NULL)
+                    {
+                      rl2_get_raster_size(raster, &width, &height);
+                      sprintf(dummy, "%u X %u", width, height);
+                      abstract += wxString::FromUTF8(dummy);
+                      rl2_destroy_raster(raster);
+                    }
+                  valid = 1;
+                }
+              if (strcmp(mime_type, "image/png") == 0)
+                {
+                  abstract = wxT("PNG icon: ");
+                  raster =
+                    rl2_raster_from_png((const unsigned char *) xblob,
+                                        xblob_size, 1);
+                  if (raster != NULL)
+                    {
+                      rl2_get_raster_size(raster, &width, &height);
+                      sprintf(dummy, "%u X %u", width, height);
+                      abstract += wxString::FromUTF8(dummy);
+                      rl2_destroy_raster(raster);
+                    }
+                  valid = 1;
+                }
+              if (strcmp(mime_type, "image/jpeg") == 0)
+                {
+                  abstract = wxT("JPEG icon: ");
+                  raster =
+                    rl2_raster_from_jpeg((const unsigned char *) xblob,
+                                         xblob_size);
+                  if (raster != NULL)
+                    {
+                      rl2_get_raster_size(raster, &width, &height);
+                      sprintf(dummy, "%u X %u", width, height);
+                      abstract += wxString::FromUTF8(dummy);
+                      rl2_destroy_raster(raster);
+                    }
+                  valid = 1;
+                }
+              if (strcmp(mime_type, "image/svg+xml") == 0)
+                {
+                  abstract = wxT("SVG symbol");
+                  valid = 1;
+                }
+            }
+      } else
+        goto invalid;
+    }
+  sqlite3_finalize(stmt);
+  stmt = NULL;
+  if (!valid)
+    goto invalid;
+  *blob = xblob;
+  *blob_size = xblob_size;
+  return true;
+
+invalid:
+  if (stmt != NULL)
+    sqlite3_finalize(stmt);
+  free(xblob);
+  *blob = NULL;
+  *blob_size = 0;
+  return false;
+}
+
+bool LoadExternalGraphicDialog::RegisterExternalGraphic(sqlite3_stmt * stmt,
+                                                        const char *xlink_href,
+                                                        const char *title,
+                                                        const char *abstract,
+                                                        const char *filename,
+                                                        void *blob,
+                                                        int blob_size)
+{
+//
+// attempting to register the new Raster Style
+//
+  int ret;
+  int valid = 0;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, xlink_href, strlen(xlink_href), SQLITE_STATIC);
+  sqlite3_bind_blob(stmt, 2, blob, blob_size, free);
+  sqlite3_bind_text(stmt, 3, title, strlen(title), SQLITE_STATIC);
+  sqlite3_bind_text(stmt, 4, abstract, strlen(abstract), SQLITE_STATIC);
+  sqlite3_bind_text(stmt, 5, filename, strlen(filename), SQLITE_STATIC);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        return false;
+    }
+  if (valid)
+    return true;
+  return false;
+}
+
+void LoadExternalGraphicDialog::DoRunLoad()
+{
+//
+// executing the Load External Graphic resource(s) process in a separate Thread
+//
+#ifdef _WIN32
+  HANDLE thread_handle;
+  DWORD dwThreadId;
+#else
+  pthread_t thread_id;
+#endif
+  Params.Initialize(MainFrame, this, Paths);
+#ifdef _WIN32
+  thread_handle =
+    CreateThread(NULL, 0, DoExecuteExternalGraphicLoad, &Params, 0,
+                 &dwThreadId);
+  SetThreadPriority(thread_handle, THREAD_PRIORITY_IDLE);
+#else
+  int ok_prior = 0;
+  int policy;
+  int min_prio;
+  pthread_attr_t attr;
+  struct sched_param sp;
+  pthread_attr_init(&attr);
+  if (pthread_attr_setschedpolicy(&attr, SCHED_RR) == 0)
+    {
+      // attempting to set the lowest priority  
+      if (pthread_attr_getschedpolicy(&attr, &policy) == 0)
+        {
+          min_prio = sched_get_priority_min(policy);
+          sp.sched_priority = min_prio;
+          if (pthread_attr_setschedparam(&attr, &sp) == 0)
+            {
+              // ok, setting the lowest priority  
+              ok_prior = 1;
+              pthread_create(&thread_id, &attr, DoExecuteExternalGraphicLoad,
+                             &Params);
+            }
+        }
+    }
+  if (!ok_prior)
+    {
+      // failure: using standard priority
+      pthread_create(&thread_id, NULL, DoExecuteExternalGraphicLoad, &Params);
+    }
+#endif
+}
+
+void LoadExternalGraphicDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxButton *loadBtn = (wxButton *) FindWindow(wxID_OK);
+  wxButton *quitBtn = (wxButton *) FindWindow(wxID_CANCEL);
+  wxButton *abortBtn = (wxButton *) FindWindow(ID_LOAD_ABORT);
+  loadBtn->Enable(false);
+  quitBtn->Enable(false);
+  abortBtn->Enable(true);
+  ::wxBeginBusyCursor();
+  char *errMsg = NULL;
+  int ret = sqlite3_exec(MainFrame->GetSqlite(), "BEGIN", NULL, NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") +
+                   wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      ::wxEndBusyCursor();
+      return;
+    }
+  ret =
+    sqlite3_exec(MainFrame->GetSqlite(), "SELECT CreateStylingTables()", NULL,
+                 NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("CreateStylingTables() error: ") +
+                   wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      ::wxEndBusyCursor();
+      return;
+    }
+
+  DoRunLoad();
+}
+
+bool UnregisterExternalGraphicDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  List = MainFrame->FindExternalGraphic(false);
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Unregistering an External Graphic resource")) ==
+      false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void UnregisterExternalGraphicDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT
+                                         ("Registered External Graphic resources"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_SLD_SE_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  ExternalGraphic *pE = List->GetFirst();
+  while (pE)
+    {
+      // counting how many lines are there
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 5, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("xlink:href"));
+  GridCtrl->SetColLabelValue(1, wxT("Graphic"));
+  GridCtrl->SetColLabelValue(2, wxT("Title"));
+  GridCtrl->SetColLabelValue(3, wxT("Abstract"));
+  GridCtrl->SetColLabelValue(4, wxT("MimeType"));
+  count = 0;
+  pE = List->GetFirst();
+  while (pE)
+    {
+      // feeding grid rows
+      GridCtrl->SetCellValue(count, 0, pE->GetXLinkHref());
+      MyGraphicCellRenderer *renderer = new MyGraphicCellRenderer;
+      renderer->SetGraphic(pE->GetGraphic());
+      GridCtrl->SetCellRenderer(count, 1, renderer);
+      GridCtrl->SetCellValue(count, 2, pE->GetTitle());
+      GridCtrl->SetCellValue(count, 3, pE->GetAbstract());
+      GridCtrl->SetCellValue(count, 4, pE->GetMimeType());
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Unregister"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel"));
+  btnBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & UnregisterExternalGraphicDialog::OnOk);
+}
+
+bool UnregisterExternalGraphicDialog::DoUnregisterExternalGraphic(const char
+                                                                  *xlink_href)
+{
+//
+// attempting to unregister the External Graphic resource
+//
+  int ret;
+  int valid = 0;
+  const char *sql;
+  sqlite3_stmt *stmt = NULL;
+
+  sql = "SELECT SE_UnregisterExternalGraphic(?)";
+  ret =
+    sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, xlink_href, strlen(xlink_href), SQLITE_STATIC);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (valid)
+    return true;
+  return false;
+}
+
+void UnregisterExternalGraphicDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  int selCount = 0;
+  wxString xlink_href;
+  for (int i = 0; i < GridCtrl->GetNumberRows(); i++)
+    {
+      if (GridCtrl->IsInSelection(i, 0) == true)
+        {
+          xlink_href = GridCtrl->GetCellValue(i, 0);
+          selCount++;
+        }
+    }
+  if (selCount < 1)
+    {
+      wxMessageBox(wxT
+                   ("You must select an External Graphic resource to be unregistered !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (selCount > 1)
+    {
+      wxString msg =
+        wxT
+        ("You must select just a single External Graphic resource to be unregistered !!!\n");
+      msg += wxT("Multiple selection is not supported");
+      wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  ::wxBeginBusyCursor();
+  if (DoUnregisterExternalGraphic(xlink_href.ToUTF8()) == true)
+    {
+      ::wxEndBusyCursor();
+      wxMessageBox(wxT("External Graphic (xlink:href=") + xlink_href +
+                   wxT(") successfully unregistered"),
+                   wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  } else
+    {
+      ::wxEndBusyCursor();
+      wxMessageBox(wxT
+                   ("Some error occurred: unable to unregister External Graphic (xlink:href=")
+                   + xlink_href + wxT(")"), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+    }
+
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool LoadTextFontDialog::Create(MyFrame * parent, wxArrayString & paths,
+                                wxString & path)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Paths = paths;
+  Path = path;
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Loading New Text Font(s)")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void LoadTextFontDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// first row: files to be imported
+  wxBoxSizer *fileSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(fileSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *fileLabel =
+    new wxStaticText(this, wxID_STATIC, wxT("Import &File(s):"));
+  fileSizer->Add(fileLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *filesCtrl = new wxTextCtrl(this, wxID_ANY, Path,
+                                         wxDefaultPosition, wxSize(600, 60),
+                                         wxTE_MULTILINE | wxTE_READONLY);
+  fileSizer->Add(filesCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: progress report
+  wxBoxSizer *progrSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(progrSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *doneCtrl = new wxTextCtrl(this, ID_LOAD_FONT_DONE, ListDone,
+                                        wxDefaultPosition, wxSize(650, 100),
+                                        wxTE_MULTILINE | wxTE_READONLY |
+                                        wxTE_RICH2);
+  progrSizer->Add(doneCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+
+// OK - CANCEL buttons
+  wxBoxSizer *okCancelBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Import"));
+  okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Quit"));
+  okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *abort = new wxButton(this, ID_LOAD_ABORT, wxT("&Abort"));
+  abort->Enable(false);
+  okCancelBox->Add(abort, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadTextFontDialog::OnOk);
+  Connect(ID_LOAD_ABORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadTextFontDialog::OnCmdAbort);
+  Connect(ID_LOAD_FONT_START, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadTextFontDialog::OnRequestStart);
+  Connect(ID_LOAD_FONT_STOP, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadTextFontDialog::OnRequestStop);
+  Connect(ID_LOAD_FONT_SKIP, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadTextFontDialog::OnRequestSkip);
+  Connect(ID_LOAD_FONT_THREAD_FINISHED, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & LoadTextFontDialog::OnThreadFinished);
+}
+
+void LoadTextFontDialog::OnCmdAbort(wxCommandEvent & WXUNUSED(event))
+{
+//
+// aborting the Text Font(s) Import process
+//
+  if (Params.IsAbortPending() == true)
+    return;
+  Params.RequestAbort();
+  wxString report =
+    wxT("\nan ABORT request is now pending and will be accepted ASAP");
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_FONT_DONE);
+  wxColour fore = wxColour(255, 255, 255);
+  wxColour back = wxColour(192, 0, 0);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(report);
+}
+
+void LoadTextFontDialog::OnRequestStart(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_FONT_DONE);
+  wxColour fore = wxColour(255, 255, 255);
+  wxColour back = wxColour(0, 0, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(msg);
+  doneCtrl->MarkDirty();
+}
+
+void LoadTextFontDialog::OnRequestStop(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_FONT_DONE);
+  ListDone += msg;
+  doneCtrl->Clear();
+  wxColour fore = wxColour(0, 0, 0);
+  wxColour back = wxColour(255, 255, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(ListDone);
+  doneCtrl->MarkDirty();
+}
+
+void LoadTextFontDialog::OnRequestSkip(wxCommandEvent & event)
+{
+//
+// updating the Progress Report
+//
+  wxString msg = event.GetString();
+  wxTextCtrl *doneCtrl = (wxTextCtrl *) FindWindow(ID_LOAD_FONT_DONE);
+  ListDone += msg;
+  doneCtrl->Clear();
+  wxColour fore = wxColour(0, 0, 0);
+  wxColour back = wxColour(255, 0, 255);
+  wxTextAttr style = wxTextAttr(fore, back);
+  doneCtrl->SetDefaultStyle(style);
+  doneCtrl->AppendText(ListDone);
+  doneCtrl->MarkDirty();
+}
+
+#ifdef _WIN32
+DWORD WINAPI DoExecuteTextFontLoad(void *arg)
+#else
+void *DoExecuteTextFontLoad(void *arg)
+#endif
+{
+//
+// threaded function: processing a Text Font Import operation
+//
+  TextFontLoadParams *params = (TextFontLoadParams *) arg;
+  const char *sql;
+  int ret;
+  sqlite3_stmt *stmt = NULL;
+  int count = params->GetPathsCount();
+  int i;
+  clock_t clock_start;
+  clock_t clock_end;
+  double seconds;
+  char elapsed[64];
+  char ordinal[64];
+  wxString report;
+  wxString path;
+  wxCommandEvent evt_start(wxEVT_COMMAND_BUTTON_CLICKED, ID_LOAD_FONT_START);
+  wxCommandEvent evt_stop(wxEVT_COMMAND_BUTTON_CLICKED, ID_LOAD_FONT_STOP);
+  wxCommandEvent evt_skip(wxEVT_COMMAND_BUTTON_CLICKED, ID_LOAD_FONT_SKIP);
+
+  sql = "SELECT RL2_LoadFontFromFile(?)";
+  ret =
+    sqlite3_prepare_v2(params->GetMainFrame()->GetSqlite(), sql, strlen(sql),
+                       &stmt, NULL);
+  if (ret != SQLITE_OK)
+    {
+      params->SetError();
+      goto error;
+    }
+
+  for (i = 0; i < count; i++)
+    {
+      // loading and verifying each Text Font resource
+      if (params->IsAbortPending() == true)
+        {
+          report = wxT("STOP .... aborted by the user !!!!");
+          evt_start.SetString(report);
+          params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_start);
+          break;
+        }
+      path = params->GetPathByIndex(i);
+      params->SetCurrentPath(path);
+      report = wxT("Loading and Validating: ") + path;
+      evt_start.SetString(report);
+      params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_start);
+      clock_start = clock();
+      wxString abstract;
+      if (params->GetDlg()->RegisterTextFont(stmt, path.ToUTF8()) != true)
+        {
+          clock_end = clock();
+          seconds =
+            (double) (clock_end - clock_start) / (double) CLOCKS_PER_SEC;
+          MyResultSetView::FormatElapsedTime(seconds, elapsed);
+          sprintf(ordinal, "discarded %d/%d (not a valid Text Font): ",
+                  i + 1, count);
+          report =
+            wxString::FromUTF8(ordinal) + path + wxT("    [") +
+            wxString::FromUTF8(elapsed) + wxT("]\n");
+          evt_skip.SetString(report);
+          params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_skip);
+          continue;
+        }
+      clock_end = clock();
+      seconds = (double) (clock_end - clock_start) / (double) CLOCKS_PER_SEC;
+      MyResultSetView::FormatElapsedTime(seconds, elapsed);
+      sprintf(ordinal, "done %d/%d: ", i + 1, count);
+      report =
+        wxString::FromUTF8(ordinal) + path + wxT("    [") +
+        wxString::FromUTF8(elapsed) + wxT("]\n");
+      evt_stop.SetString(report);
+      params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_stop);
+      params->Done();
+    }
+  sqlite3_finalize(stmt);
+  goto end;
+
+error:
+  sqlite3_finalize(stmt);
+  report = wxT("FAILED: ") + path;
+  evt_stop.SetString(report);
+  params->GetDlg()->GetEventHandler()->AddPendingEvent(evt_stop);
+  params->SetError();
+end:
+  wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED,
+                       ID_LOAD_FONT_THREAD_FINISHED);
+  params->GetDlg()->GetEventHandler()->AddPendingEvent(event);
+#ifdef _WIN32
+  return 0;
+#else
+  pthread_exit(NULL);
+#endif
+}
+
+void LoadTextFontDialog::OnThreadFinished(wxCommandEvent & WXUNUSED(event))
+{
+// resuming execution when the Import Text Font thread quits
+  ::wxEndBusyCursor();
+  wxButton *quitBtn = (wxButton *) FindWindow(wxID_CANCEL);
+  wxButton *abortBtn = (wxButton *) FindWindow(ID_LOAD_ABORT);
+  quitBtn->Enable(true);
+  abortBtn->Enable(false);
+  sqlite3_exec(Params.GetMainFrame()->GetSqlite(), "COMMIT", NULL, NULL, NULL);
+  if (Params.GetError() == true)
+    {
+      char dummy[80];
+      sprintf(dummy,
+              "%d TextFonts have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy) +
+                   wxT("\n\nA fatal error occurred while loading:\n") +
+                   Params.GetCurrentPath(), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+  } else if (Params.IsAbortPending() == true)
+    {
+      char dummy[80];
+      sprintf(dummy,
+              "%d TextFonts have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy) +
+                   wxT("\n\nStopped by an Abort user request"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+  } else
+    {
+      char dummy[80];
+      sprintf(dummy,
+              "%d TextFonts have been successfully imported",
+              Params.GetCount());
+      wxMessageBox(wxString::FromUTF8(dummy), wxT("spatialite_gui"),
+                   wxOK | wxICON_INFORMATION, this);
+    }
+}
+
+bool LoadTextFontDialog::RegisterTextFont(sqlite3_stmt * stmt, const char *path)
+{
+//
+// attempting to register the new Text Font
+//
+  int ret;
+  int valid = 0;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_text(stmt, 1, path, strlen(path), SQLITE_STATIC);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        return false;
+    }
+  if (valid)
+    return true;
+  return false;
+}
+
+void LoadTextFontDialog::DoRunLoad()
+{
+//
+// executing the Load Text Font(s) process in a separate Thread
+//
+#ifdef _WIN32
+  HANDLE thread_handle;
+  DWORD dwThreadId;
+#else
+  pthread_t thread_id;
+#endif
+  Params.Initialize(MainFrame, this, Paths);
+#ifdef _WIN32
+  thread_handle =
+    CreateThread(NULL, 0, DoExecuteTextFontLoad, &Params, 0, &dwThreadId);
+  SetThreadPriority(thread_handle, THREAD_PRIORITY_IDLE);
+#else
+  int ok_prior = 0;
+  int policy;
+  int min_prio;
+  pthread_attr_t attr;
+  struct sched_param sp;
+  pthread_attr_init(&attr);
+  if (pthread_attr_setschedpolicy(&attr, SCHED_RR) == 0)
+    {
+      // attempting to set the lowest priority  
+      if (pthread_attr_getschedpolicy(&attr, &policy) == 0)
+        {
+          min_prio = sched_get_priority_min(policy);
+          sp.sched_priority = min_prio;
+          if (pthread_attr_setschedparam(&attr, &sp) == 0)
+            {
+              // ok, setting the lowest priority  
+              ok_prior = 1;
+              pthread_create(&thread_id, &attr, DoExecuteTextFontLoad, &Params);
+            }
+        }
+    }
+  if (!ok_prior)
+    {
+      // failure: using standard priority
+      pthread_create(&thread_id, NULL, DoExecuteTextFontLoad, &Params);
+    }
+#endif
+}
+
+void LoadTextFontDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxButton *loadBtn = (wxButton *) FindWindow(wxID_OK);
+  wxButton *quitBtn = (wxButton *) FindWindow(wxID_CANCEL);
+  wxButton *abortBtn = (wxButton *) FindWindow(ID_LOAD_ABORT);
+  loadBtn->Enable(false);
+  quitBtn->Enable(false);
+  abortBtn->Enable(true);
+  ::wxBeginBusyCursor();
+  char *errMsg = NULL;
+  int ret = sqlite3_exec(MainFrame->GetSqlite(), "BEGIN", NULL, NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("SQLite SQL error: ") +
+                   wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      ::wxEndBusyCursor();
+      return;
+    }
+  ret =
+    sqlite3_exec(MainFrame->GetSqlite(), "SELECT CreateStylingTables()", NULL,
+                 NULL, &errMsg);
+  if (ret != SQLITE_OK)
+    {
+      wxMessageBox(wxT("CreateStylingTables() error: ") +
+                   wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+      sqlite3_free(errMsg);
+      ::wxEndBusyCursor();
+      return;
+    }
+  DoRunLoad();
+}
+
+bool UnregisterTextFontDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  List = MainFrame->FindTextFont();
+  if (wxDialog::Create(parent, wxID_ANY,
+                       wxT("Unregistering a Text Font")) == false)
+    return false;
+// populates individual controls
+  CreateControls();
+// sets dialog sizer
+  GetSizer()->Fit(this);
+  GetSizer()->SetSizeHints(this);
+// centers the dialog window
+  Centre();
+  return true;
+}
+
+void UnregisterTextFontDialog::CreateControls()
+{
+//
+// creating individual control and setting initial values
+//
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  this->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// a GRID to show results
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *gridBox = new wxStaticBox(this, wxID_STATIC,
+                                         wxT("Registered Text Fonts"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxVERTICAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(this, ID_SLD_SE_GRID, wxDefaultPosition, wxSize(640, 200),
+               wxALWAYS_SHOW_SB);
+  int count = 0;
+  TextFont *pF = List->GetFirst();
+  while (pF)
+    {
+      // counting how many lines are there
+      count++;
+      pF = pF->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 4, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("FaceName"));
+  GridCtrl->SetColLabelValue(1, wxT("Bold"));
+  GridCtrl->SetColLabelValue(2, wxT("Italic"));
+  GridCtrl->SetColLabelValue(3, wxT("Sample"));
+  count = 0;
+  pF = List->GetFirst();
+  while (pF)
+    {
+      // feeding grid rows
+      GridCtrl->SetCellValue(count, 0, pF->GetFacename());
+      MyFontCellRenderer *renderer = new MyFontCellRenderer;
+      if (pF->IsBold() == true)
+        GridCtrl->SetCellValue(count, 1, wxT("YES"));
+      if (pF->IsItalic() == true)
+        GridCtrl->SetCellValue(count, 2, wxT("YES"));
+      renderer->SetFontExample(pF->GetFontExample());
+      GridCtrl->SetCellRenderer(count, 3, renderer);
+      GridCtrl->SetCellBackgroundColour(count, 3, wxColour(255, 255, 255));
+      count++;
+      pF = pF->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// buttons
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Unregister"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *cancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel"));
+  btnBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// appends event handler for OK button
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & UnregisterTextFontDialog::OnOk);
+}
+
+bool UnregisterTextFontDialog::DoUnregisterTextFont(int font_id)
+{
+//
+// attempting to unregister the Text Font
+//
+  int ret;
+  int valid = 0;
+  const char *sql;
+  sqlite3_stmt *stmt = NULL;
+
+  sql = "DELETE FROM SE_Fonts WHERE font_id = ?";
+  ret =
+    sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_int(stmt, 1, font_id);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        {
+          valid = 1;
+          break;
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (valid)
+    return true;
+  return false;
+}
+
+void UnregisterTextFontDialog::OnOk(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  int selCount = 0;
+  int FontId;
+  for (int i = 0; i < GridCtrl->GetNumberRows(); i++)
+    {
+      if (GridCtrl->IsInSelection(i, 0) == true)
+        {
+          wxString cell_id = GridCtrl->GetCellValue(i, 0);
+          long id;
+          cell_id.ToLong(&id);
+          FontId = id;
+          selCount++;
+        }
+    }
+  if (selCount < 1)
+    {
+      wxMessageBox(wxT
+                   ("You must select a Text Font to be unregistered !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  if (selCount > 1)
+    {
+      wxString msg =
+        wxT("You must select just a single Text Font to be unregistered !!!\n");
+      msg += wxT("Multiple selection is not supported");
+      wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return;
+    }
+  ::wxBeginBusyCursor();
+  char dummy[128];
+  sprintf(dummy, "(FontID=%d)", FontId);
+  if (DoUnregisterTextFont(FontId) == true)
+    {
+      ::wxEndBusyCursor();
+      wxMessageBox(wxT("Text Font ") + wxString::FromUTF8(dummy) +
+                   wxT(" successfully unregistered"),
+                   wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  } else
+    {
+      ::wxEndBusyCursor();
+      wxMessageBox(wxT
+                   ("Some error occurred: unable to unregister Text Font ")
+                   + wxString::FromUTF8(dummy), wxT("spatialite_gui"),
+                   wxOK | wxICON_ERROR, this);
+    }
+
+  wxDialog::EndModal(wxID_OK);
+}
+
+TextFontList *MyFrame::FindTextFont()
+{
+// will retrieve all registered Text Fonts
+  TextFontList *list = new TextFontList();
+  sqlite3_stmt *stmt = NULL;
+  const char *sql;
+
+  sql = "SELECT font FROM SE_fonts";
+  int ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    {
+      delete list;
+      return NULL;
+    }
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          const unsigned char *blob = NULL;
+          int blob_sz = 0;
+          if (sqlite3_column_type(stmt, 0) == SQLITE_BLOB)
+            {
+              blob = (const unsigned char *) sqlite3_column_blob(stmt, 0);
+              blob_sz = sqlite3_column_bytes(stmt, 0);
+              list->Add(RL2PrivateData, blob, blob_sz);
+            }
+      } else
+        {
+          sqlite3_finalize(stmt);
+          delete list;
+          return NULL;
+        }
+    }
+  sqlite3_finalize(stmt);
+  return list;
+}
+
+TextFont::TextFont(const void *priv_data, const unsigned char *blob,
+                   int blob_sz)
+{
+// ctor
+  Next = NULL;
+  char *facename = rl2_get_encoded_font_facename(blob, blob_sz);
+  Facename = wxString::FromUTF8(facename);
+  if (facename != NULL)
+    free(facename);
+  if (rl2_is_encoded_font_bold(blob, blob_sz) <= 0)
+    Bold = false;
+  else
+    Bold = true;
+  if (rl2_is_encoded_font_italic(blob, blob_sz) <= 0)
+    Italic = false;
+  else
+    Italic = true;
+
+// creating the Font Preview
+  rl2GraphicsContextPtr ctx = rl2_graph_create_context(600, 22);
+  rl2_graph_set_brush(ctx, 255, 255, 255, 255);
+  rl2_graph_draw_rectangle(ctx, -1, -1, 602, 24);
+  const char *sample = "the quick brown fox jumps over the lazy dog";
+  rl2GraphicsFontPtr font =
+    rl2_graph_create_TrueType_font(priv_data, blob, blob_sz, 16.0);
+  rl2_graph_set_font(ctx, font);
+  rl2_graph_draw_text(ctx, sample, 5.0, 18.0, 0.0, 0.0, 0.0);
+  rl2_graph_release_font(ctx);
+  rl2_graph_destroy_font(font);
+// creating a raster image
+  unsigned char *rgb = rl2_graph_get_context_rgb_array(ctx);
+  rl2_graph_destroy_context(ctx);
+  rl2RasterPtr raster =
+    rl2_create_raster(600, 22, RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3, rgb,
+                      600 * 22 * 3, NULL, NULL, 0, NULL);
+  unsigned char *rgbaArray = NULL;
+  int rgbaSize;
+  unsigned int width;
+  unsigned int height;
+  wxImage *Image = NULL;
+  if (raster)
+    {
+      if (rl2_get_raster_size(raster, &width, &height) == RL2_OK)
+        {
+          if (rl2_raster_data_to_RGBA(raster, &rgbaArray, &rgbaSize) != RL2_OK)
+            rgbaArray = NULL;
+        }
+      rl2_destroy_raster(raster);
+    }
+  if (rgbaArray)
+    {
+      // creating the Image from RGB array
+      unsigned int x;
+      unsigned int y;
+      Image = new wxImage(width, height);
+      unsigned char *p = rgbaArray;
+      Image->SetAlpha();
+      for (y = 0; y < height; y++)
+        {
+          for (x = 0; x < width; x++)
+            {
+              unsigned char r = *p++;
+              unsigned char g = *p++;
+              unsigned char b = *p++;
+              unsigned char alpha = *p++;
+              Image->SetRGB(x, y, r, g, b);
+              Image->SetAlpha(x, y, alpha);
+            }
+        }
+      free(rgbaArray);
+    }
+  if (Image != NULL)
+    FontExample = Image;
+  else
+    FontExample = new wxImage(180, 16);
+}
+
+TextFontList::~TextFontList()
+{
+// dtor
+  TextFont *pF;
+  TextFont *pFn;
+  pF = First;
+  while (pF != NULL)
+    {
+      pFn = pF->GetNext();
+      delete pF;
+      pF = pFn;
+    }
+}
+
+void TextFontList::Add(const void *priv_data, const unsigned char *blob,
+                       int blob_sz)
+{
+// inserting a new Text Font into the list
+  TextFont *pF = new TextFont(priv_data, blob, blob_sz);
+  if (First == NULL)
+    First = pF;
+  if (Last != NULL)
+    Last->SetNext(pF);
+  Last = pF;
+}
+
+void TextFontList::FindByIndex(int idx, wxString & face_name, int *style,
+                               int *weight)
+{
+// searching an entry by its position
+  TextFont *pF;
+  int count = 0;
+  pF = First;
+  while (pF != NULL)
+    {
+      if (idx == count)
+        {
+          face_name = pF->GetFacename();
+          if (pF->IsBold() == true)
+            *weight = RL2_FONTWEIGHT_BOLD;
+          else
+            *weight = RL2_FONTWEIGHT_NORMAL;
+          if (pF->IsItalic() == true)
+            *style = RL2_FONTSTYLE_ITALIC;
+          else
+            *style = RL2_FONTSTYLE_NORMAL;
+          return;
+        }
+      count++;
+      pF = pF->GetNext();
+    }
+  face_name = wxT("");
+  *style = RL2_FONTSTYLE_NORMAL;
+  *weight = RL2_FONTWEIGHT_NORMAL;
+}
+
+int TextFontList::FindByFaceName(wxString & face_name)
+{
+// searching an entry by Facename
+  TextFont *pF;
+  int count = 0;
+  pF = First;
+  while (pF != NULL)
+    {
+      if (face_name.CmpNoCase(pF->GetFacename()) == 0)
+        return count;
+      count++;
+      pF = pF->GetNext();
+    }
+  return -1;
+}
+
+void MyFontCellRenderer::Draw(wxGrid & grid, wxGridCellAttr & attr,
+                              wxDC & dc, const wxRect & rect, int row,
+                              int col, bool isSelected)
+{
+// drawing a Font Example cell
+  wxBitmap bmp = wxBitmap(*FontExample);
+  wxColour color = attr.GetBackgroundColour();
+  if (grid.IsEnabled() == false)
+    {
+      color = wxSystemSettings::GetColour(wxSYS_COLOUR_MENU);
+      wxImage img = FontExample->ConvertToGreyscale();
+      bmp = wxBitmap(img);
+    }
+  dc.SetBrush(wxBrush(color));
+  dc.SetPen(*wxTRANSPARENT_PEN);
+  dc.DrawRectangle(rect);
+  int x = (rect.GetWidth() - bmp.GetWidth()) / 2;
+  int y = (rect.GetHeight() - bmp.GetHeight()) / 2;
+  dc.DrawBitmap(bmp, rect.x + x, rect.y + y, true);
+}
diff --git a/TableTree.cpp b/TableTree.cpp
index ebd8590..472d035 100644
--- a/TableTree.cpp
+++ b/TableTree.cpp
@@ -66,6 +66,9 @@
 #include "icons/attach.xpm"
 #include "icons/checkgeom.xpm"
 #include "icons/sanegeom.xpm"
+#include "icons/coverage.xpm"
+#include "icons/coverage_tiles.xpm"
+#include "icons/vector.xpm"
 
 MyTableTree::MyTableTree(MyFrame * parent, wxWindowID id):wxTreeCtrl(parent, id)
 {
@@ -78,12 +81,14 @@ MyTableTree::MyTableTree(MyFrame * parent, wxWindowID id):wxTreeCtrl(parent, id)
   RootIsoMetadata = AppendItem(Root, wxT("ISO / INSPIRE Metadata"));
   RootStyling = AppendItem(Root, wxT("Styling (SLD/SE)"));
   RootTopologies = AppendItem(Root, wxT("Topologies"));
+  RootRasterCoverages = AppendItem(Root, wxT("Raster Coverages"));
+  RootVectorCoverages = AppendItem(Root, wxT("Vector Coverages"));
   RootMetadata = AppendItem(Root, wxT("Metadata"));
   RootInternal = AppendItem(Root, wxT("Internal Data"));
   RootSpatialIndex = AppendItem(Root, wxT("Spatial Index"));
 // setting up icons 
   Images = new wxImageList(16, 16, true);
-  wxIcon icons[22];
+  wxIcon icons[25];
   icons[0] = wxIcon(db_xpm);
   icons[1] = wxIcon(table_xpm);
   icons[2] = wxIcon(pkey_xpm);
@@ -106,6 +111,9 @@ MyTableTree::MyTableTree(MyFrame * parent, wxWindowID id):wxTreeCtrl(parent, id)
   icons[19] = wxIcon(primary_key_xpm);
   icons[20] = wxIcon(topology_xpm);
   icons[21] = wxIcon(attach_xpm);
+  icons[22] = wxIcon(coverage_xpm);
+  icons[23] = wxIcon(coverage_tiles_xpm);
+  icons[24] = wxIcon(vector_xpm);
   Images->Add(icons[0]);
   Images->Add(icons[1]);
   Images->Add(icons[2]);
@@ -128,16 +136,25 @@ MyTableTree::MyTableTree(MyFrame * parent, wxWindowID id):wxTreeCtrl(parent, id)
   Images->Add(icons[19]);
   Images->Add(icons[20]);
   Images->Add(icons[21]);
+  Images->Add(icons[22]);
+  Images->Add(icons[23]);
+  Images->Add(icons[24]);
   SetImageList(Images);
   SetItemImage(Root, 0);
   SetItemImage(RootUserData, 17);
   SetItemImage(RootTopologies, 17);
+  SetItemImage(RootRasterCoverages, 22);
+  SetItemImage(RootVectorCoverages, 24);
   SetItemImage(RootStyling, 17);
   SetItemImage(RootIsoMetadata, 17);
   SetItemImage(RootMetadata, 17);
   SetItemImage(RootInternal, 17);
   SetItemImage(RootSpatialIndex, 17);
 // setting up event handlers 
+  Connect(wxID_ANY, wxEVT_COMMAND_TREE_ITEM_COLLAPSED,
+          (wxObjectEventFunction) & MyTableTree::OnItemCollapsed);
+  Connect(wxID_ANY, wxEVT_COMMAND_TREE_ITEM_EXPANDING,
+          (wxObjectEventFunction) & MyTableTree::OnItemExpanding);
   Connect(wxID_ANY, wxEVT_COMMAND_TREE_SEL_CHANGED,
           (wxObjectEventFunction) & MyTableTree::OnSelChanged);
   Connect(wxID_ANY, wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK,
@@ -164,8 +181,12 @@ MyTableTree::MyTableTree(MyFrame * parent, wxWindowID id):wxTreeCtrl(parent, id)
           (wxObjectEventFunction) & MyTableTree::OnCmdRename);
   Connect(Tree_Select, wxEVT_COMMAND_MENU_SELECTED,
           (wxObjectEventFunction) & MyTableTree::OnCmdSelect);
+  Connect(Tree_SelectTiles, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdSelectTiles);
   Connect(Tree_Refresh, wxEVT_COMMAND_MENU_SELECTED,
           (wxObjectEventFunction) & MyTableTree::OnCmdRefresh);
+  Connect(Tree_RefreshDeferred, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnRefreshDeferred);
   Connect(Tree_Recover, wxEVT_COMMAND_MENU_SELECTED,
           (wxObjectEventFunction) & MyTableTree::OnCmdRecover);
   Connect(Tree_ShowSql, wxEVT_COMMAND_MENU_SELECTED,
@@ -234,6 +255,91 @@ MyTableTree::MyTableTree(MyFrame * parent, wxWindowID id):wxTreeCtrl(parent, id)
           (wxObjectEventFunction) & MyTableTree::OnCmdCheckGeometries);
   Connect(Tree_SaneGeom, wxEVT_COMMAND_MENU_SELECTED,
           (wxObjectEventFunction) & MyTableTree::OnCmdSanitizeGeometries);
+  Connect(Tree_NewRasterStyle, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdNewRasterStyle);
+  Connect(Tree_ReloadRasterStyle, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdReloadRasterStyle);
+  Connect(Tree_UnregisterRasterStyle, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdUnregisterRasterStyle);
+  Connect(Tree_RasterSymbolizerContrast, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdRasterSymbolizerContrast);
+  Connect(Tree_RasterSymbolizerChannelRgb, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) &
+          MyTableTree::OnCmdRasterSymbolizerChannelRgb);
+  Connect(Tree_RasterSymbolizerChannelGray, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) &
+          MyTableTree::OnCmdRasterSymbolizerChannelGray);
+  Connect(Tree_RasterSymbolizerCategorize, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) &
+          MyTableTree::OnCmdRasterSymbolizerCategorize);
+  Connect(Tree_RasterSymbolizerInterpolate, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) &
+          MyTableTree::OnCmdRasterSymbolizerInterpolate);
+  Connect(Tree_RasterSymbolizerShadedRelief, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) &
+          MyTableTree::OnCmdRasterSymbolizerShadedRelief);
+  Connect(Tree_RasterSymbolizerMonochrome, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) &
+          MyTableTree::OnCmdRasterSymbolizerMonochrome);
+  Connect(Tree_RegisterExternalGraphic, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdRegisterExternalGraphic);
+  Connect(Tree_UnregisterExternalGraphic, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) &
+          MyTableTree::OnCmdUnregisterExternalGraphic);
+  Connect(Tree_RegisterTextFont, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdRegisterTextFont);
+  Connect(Tree_UnregisterTextFont, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdUnregisterTextFont);
+  Connect(Tree_NewVectorStyle, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdNewVectorStyle);
+  Connect(Tree_ReloadVectorStyle, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdReloadVectorStyle);
+  Connect(Tree_UnregisterVectorStyle, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdUnregisterVectorStyle);
+  Connect(Tree_SimpleLineSymbolizer, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdSimpleLineSymbolizer);
+  Connect(Tree_SimplePolygonSymbolizer, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdSimplePolygonSymbolizer);
+  Connect(Tree_SimplePointSymbolizer, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdSimplePointSymbolizer);
+  Connect(Tree_SimpleTextSymbolizer, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdSimpleTextSymbolizer);
+  Connect(Tree_ImportRaster, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdImportRaster);
+  Connect(Tree_Pyramidize, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdPyramidize);
+  Connect(Tree_PyramidizeMonolithic, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdPyramidizeMonolithic);
+  Connect(Tree_DePyramidize, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdDePyramidize);
+  Connect(Tree_RasterDrop, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdRasterDrop);
+  Connect(Tree_UpdateRasterExtent, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdUpdateRasterExtent);
+  Connect(Tree_Raster_SRIDs, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdRasterSRIDs);
+  Connect(Tree_Raster_Keywords, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdRasterKeywords);
+  Connect(Tree_UpdateRasterExtentAll, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdUpdateRasterExtentAll);
+  Connect(Tree_VectorUnregister, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdVectorUnregister);
+  Connect(Tree_UpdateVectorExtent, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdUpdateVectorExtent);
+  Connect(Tree_Vector_SRIDs, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdVectorSRIDs);
+  Connect(Tree_Vector_Keywords, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdVectorKeywords);
+  Connect(Tree_UpdateVectorExtentAll, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdUpdateVectorExtentAll);
+  Connect(Tree_SldSeRasterStyles, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdSldSeRasterStyles);
+  Connect(Tree_SldSeVectorStyles, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCmdSldSeVectorStyles);
+  Connect(Tree_CreateRasterCoverage, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnCreateRasterCoverage);
+  Connect(Tree_VectorRegister, wxEVT_COMMAND_MENU_SELECTED,
+          (wxObjectEventFunction) & MyTableTree::OnRegisterVectorCoverage);
 }
 
 void MyTableTree::FlushAll()
@@ -244,6 +350,8 @@ void MyTableTree::FlushAll()
   bool ok = true;
   DeleteChildren(RootUserData);
   DeleteTopologies(RootTopologies);
+  DeleteRasterCoverages(RootRasterCoverages);
+  DeleteVectorCoverages(RootVectorCoverages);
   DeleteChildren(RootStyling);
   DeleteChildren(RootIsoMetadata);
   DeleteChildren(RootMetadata);
@@ -262,6 +370,10 @@ void MyTableTree::FlushAll()
             kill = false;
           if (child == RootTopologies)
             kill = false;
+          if (child == RootRasterCoverages)
+            kill = false;
+          if (child == RootVectorCoverages)
+            kill = false;
           if (child == RootStyling)
             kill = false;
           if (child == RootIsoMetadata)
@@ -283,6 +395,57 @@ void MyTableTree::FlushAll()
     }
 }
 
+void MyTableTree::OnItemCollapsed(wxTreeEvent & event)
+{
+// a TreeItem was collapsed - freeing all children
+  wxTreeItemId item = event.GetItem();
+  MyObject *obj = (MyObject *) GetItemData(item);
+  if (obj == NULL)
+    return;
+  switch (obj->GetType())
+    {
+      case MY_TABLE:
+      case MY_VTABLE:
+      case MY_TILE_DATA:
+      case MY_VIEW:
+        DeleteChildren(item);
+        AppendItem(item, wxT("placeholder"), 0);
+        break;
+    };
+  event.Skip();
+}
+
+void MyTableTree::OnItemExpanding(wxTreeEvent & event)
+{
+// a TreeItem is to be expanded - appending all children
+  wxTreeItemId item = event.GetItem();
+  MyObject *obj = (MyObject *) GetItemData(item);
+  if (obj == NULL)
+    return;
+  switch (obj->GetType())
+    {
+      case MY_TABLE:
+      case MY_VTABLE:
+      case MY_TILE_DATA:
+        DeleteChildren(item);
+        if (obj->GetDbAlias().Len() == 0)
+          ExpandTable(item);
+        else
+          ExpandAttachedTable(item);
+        EnsureVisible(item);
+        return;
+      case MY_VIEW:
+        DeleteChildren(item);
+        if (obj->GetDbAlias().Len() == 0)
+          ExpandView(item);
+        else
+          ExpandAttachedView(item);
+        EnsureVisible(item);
+        return;
+    };
+  event.Skip();
+}
+
 void MyTableTree::DeleteTopologies(wxTreeItemId & RootTopologies)
 {
 // deleting Topology Nodes
@@ -290,11 +453,31 @@ void MyTableTree::DeleteTopologies(wxTreeItemId & RootTopologies)
   DeleteChildren(RootTopologies);
 }
 
-wxTreeItemId & MyTableTree::GetRootNode(wxString & tableName)
+void MyTableTree::DeleteRasterCoverages(wxTreeItemId & RootRasterCoverages)
+{
+// deleting Raster Coverage Nodes
+  RasterCoverages.Flush();
+  DeleteChildren(RootRasterCoverages);
+}
+
+void MyTableTree::DeleteVectorCoverages(wxTreeItemId & RootVectorCoverages)
+{
+// deleting Vector Coverage Nodes
+  VectorCoverages.Flush();
+  DeleteChildren(RootVectorCoverages);
+}
+
+wxTreeItemId & MyTableTree::GetRootNode(wxString & tableName,
+                                        bool * is_coverage, bool * tile_data)
 {
 //
 // determines the Table Root Node 
 //
+  bool isTileData = false;
+  if (is_coverage != NULL)
+    *is_coverage = false;
+  if (tile_data != NULL)
+    *tile_data = false;
   if (tableName == wxT("geometry_columns"))
     return RootMetadata;
   if (tableName == wxT("views_geometry_columns"))
@@ -303,6 +486,10 @@ wxTreeItemId & MyTableTree::GetRootNode(wxString & tableName)
     return RootMetadata;
   if (tableName == wxT("spatial_ref_sys"))
     return RootMetadata;
+  if (tableName == wxT("spatial_ref_sys_aux"))
+    return RootMetadata;
+  if (tableName == wxT("spatial_ref_sys_all"))
+    return RootMetadata;
   if (tableName == wxT("geom_cols_ref_sys"))
     return RootMetadata;
   if (tableName == wxT("geometry_columns_time"))
@@ -311,8 +498,20 @@ wxTreeItemId & MyTableTree::GetRootNode(wxString & tableName)
     return RootMetadata;
   if (tableName == wxT("raster_coverages"))
     return RootMetadata;
+  if (tableName == wxT("raster_coverages_srid"))
+    return RootMetadata;
+  if (tableName == wxT("raster_coverages_keyword"))
+    return RootMetadata;
   if (tableName == wxT("raster_coverages_ref_sys"))
     return RootMetadata;
+  if (tableName == wxT("vector_coverages"))
+    return RootMetadata;
+  if (tableName == wxT("vector_coverages_srid"))
+    return RootMetadata;
+  if (tableName == wxT("vector_coverages_keyword"))
+    return RootMetadata;
+  if (tableName == wxT("vector_coverages_ref_sys"))
+    return RootMetadata;
   if (tableName == wxT("vector_layers"))
     return RootMetadata;
   if (tableName == wxT("topology_master"))
@@ -374,25 +573,47 @@ wxTreeItemId & MyTableTree::GetRootNode(wxString & tableName)
     return RootInternal;
   if (tableName == wxT("sql_statements_log"))
     return RootInternal;
+  if (tableName == wxT("wms_server_log"))
+    return RootInternal;
+  if (tableName == wxT("ElementaryGeometries"))
+    return RootInternal;
 
   if (tableName == wxT("SE_external_graphics"))
     return RootStyling;
+  if (tableName == wxT("SE_fonts"))
+    return RootStyling;
   if (tableName == wxT("SE_external_graphics_view"))
     return RootStyling;
+  if (tableName == wxT("SE_fonts_view"))
+    return RootStyling;
+  if (tableName == wxT("SE_raster_styles"))
+    return RootStyling;
   if (tableName == wxT("SE_raster_styled_layers"))
     return RootStyling;
+  if (tableName == wxT("SE_raster_styles_view"))
+    return RootStyling;
   if (tableName == wxT("SE_raster_styled_layers_view"))
     return RootStyling;
+  if (tableName == wxT("SE_vector_styles"))
+    return RootStyling;
   if (tableName == wxT("SE_vector_styled_layers"))
     return RootStyling;
+  if (tableName == wxT("SE_vector_styles_view"))
+    return RootStyling;
   if (tableName == wxT("SE_vector_styled_layers_view"))
     return RootStyling;
   if (tableName == wxT("SE_styled_groups"))
     return RootStyling;
   if (tableName == wxT("SE_styled_group_refs"))
     return RootStyling;
+  if (tableName == wxT("SE_styled_group_styles"))
+    return RootStyling;
   if (tableName == wxT("SE_styled_groups_view"))
     return RootStyling;
+  if (tableName == wxT("SE_group_styles"))
+    return RootStyling;
+  if (tableName == wxT("SE_group_styles_view"))
+    return RootStyling;
 
   if (tableName == wxT("ISO_metadata"))
     return RootIsoMetadata;
@@ -408,14 +629,30 @@ wxTreeItemId & MyTableTree::GetRootNode(wxString & tableName)
   wxTreeItemId *topologyNode = Topologies.FindNode(tableName);
   if (topologyNode != NULL)
     return *topologyNode;
+  wxTreeItemId *coverageNode = RasterCoverages.FindNode(tableName, &isTileData);
+  if (coverageNode != NULL)
+    {
+      if (is_coverage != NULL)
+        *is_coverage = true;
+      if (tile_data != NULL)
+        *tile_data = isTileData;
+      return *coverageNode;
+    }
   return RootUserData;
 }
 
-wxTreeItemId & MyTableTree::GetRootNode(wxString & tableName, RootNodes * nodes)
+wxTreeItemId & MyTableTree::GetAltRootNode(wxString & tableName,
+                                           RootNodes * nodes,
+                                           bool * is_coverage, bool * tile_data)
 {
 //
 // determines the Table Root Node [Attached DB]
 //
+  bool isTileData = false;
+  if (is_coverage != NULL)
+    *is_coverage = false;
+  if (tile_data != NULL)
+    *tile_data = false;
   if (tableName == wxT("geometry_columns"))
     return nodes->GetRootMetadata();
   if (tableName == wxT("views_geometry_columns"))
@@ -489,47 +726,92 @@ wxTreeItemId & MyTableTree::GetRootNode(wxString & tableName, RootNodes * nodes)
     return nodes->GetRootInternal();
   if (tableName == wxT("sql_statements_log"))
     return nodes->GetRootInternal();
+  if (tableName == wxT("wms_server_log"))
+    return nodes->GetRootInternal();
+  if (tableName == wxT("ElementaryGeometries"))
+    return nodes->GetRootInternal();
 
   if (tableName == wxT("SpatialIndex"))
     return nodes->GetRootSpatialIndex();
   if (MainFrame->IsSpatialIndex(nodes->GetDbAlias(), tableName) == true)
     return nodes->GetRootSpatialIndex();
-  wxTreeItemId *topologyNode = Topologies.FindNode(tableName);
+  wxTreeItemId *topologyNode = AltTopologies.FindNode(tableName);
   if (topologyNode != NULL)
     return *topologyNode;
+  wxTreeItemId *coverageNode =
+    AltRasterCoverages.FindNode(tableName, &isTileData);
+  if (coverageNode != NULL)
+    {
+      if (is_coverage != NULL)
+        *is_coverage = true;
+      if (tile_data != NULL)
+        *tile_data = isTileData;
+      return *coverageNode;
+    }
   return nodes->GetRootUserData();
 }
 
-void MyTableTree::AddTable(wxString & tableName, bool virtualTable, bool tmp)
+void MyTableTree::AddTable(wxString & tableName, bool virtualTable,
+                           bool geometry, bool tmp)
 {
 //
 // appends a table to the TREE list
 //
-  MyTableInfo list;
-  MyColumnInfo *col;
-  MyIndexInfo *idx;
-  MyTriggerInfo *trgr;
   wxTreeItemId item;
-  wxTreeItemId item2;
-  wxString columnInfo;
-  wxString indexInfo;
-  wxString triggerInfo;
+  wxTreeItemData *data;
+  bool isCoverage = false;
+  bool isTileData = false;
   int icon = 1;
   if (virtualTable == true)
     icon = 8;
   if (tmp == true)
     icon = 14;
-  wxTreeItemId rootNode = GetRootNode(tableName);
-  item = AppendItem(rootNode, tableName, icon);
+  if (geometry == true)
+    {
+      if (virtualTable == false)
+        icon = 10;
+      else
+        icon = 13;
+    }
+  wxTreeItemId rootNode = GetRootNode(tableName, &isCoverage, &isTileData);
+  if (isTileData == true)
+    icon = 23;
   if (virtualTable == true)
-    SetItemData(item,
-                (wxTreeItemData *) (new MyObject(MY_VTABLE, tableName, tmp)));
+    data = (wxTreeItemData *) (new MyObject(MY_VTABLE, tableName, tmp));
+  else if (isTileData == true)
+    data = (wxTreeItemData *) (new MyObject(MY_TILE_DATA, tableName, tmp));
   else
-    SetItemData(item,
-                (wxTreeItemData *) (new MyObject(MY_TABLE, tableName, tmp)));
+    data =
+      (wxTreeItemData *) (new MyObject(MY_TABLE, tableName, tmp, isCoverage));
+  item = AppendItem(rootNode, tableName, icon, -1, data);
+  AppendItem(item, wxT("placeholder"), 0);
+}
+
+void MyTableTree::ExpandTable(wxTreeItemId & item)
+{
+//
+// expands a TreeItem of the TABLE type
+//
+  MyTableInfo list;
+  MyColumnInfo *col;
+  MyIndexInfo *idx;
+  MyTriggerInfo *trgr;
+  wxTreeItemId item2;
+  wxString columnInfo;
+  wxString indexInfo;
+  wxString triggerInfo;
+  MyObject *obj = (MyObject *) GetItemData(item);
+  if (obj == NULL)
+    return;
+  wxString tableName = obj->GetName();
+  bool virtualTable = false;
+  if (obj->GetType() == MY_VTABLE)
+    virtualTable = true;
+
   MainFrame->GetTableColumns(tableName, &list);
   MainFrame->GetTableIndices(tableName, &list);
   MainFrame->GetTableTriggers(tableName, &list);
+  MainFrame->CheckGPKG(tableName, &list);
   col = list.GetFirstColumn();
   while (col)
     {
@@ -538,12 +820,8 @@ void MyTableTree::AddTable(wxString & tableName, bool virtualTable, bool tmp)
         icon = 2;
       else
         {
-          if (col->IsGeometry() == true)
+          if (col->IsGeometry() == true || col->IsGPKGGeometry() == true)
             {
-              if (virtualTable == false)
-                SetItemImage(item, 10);
-              else
-                SetItemImage(item, 13);
               if (col->IsGeometryIndex() == true)
                 icon = 7;
               else if (col->IsMbrCache() == true)
@@ -564,6 +842,13 @@ void MyTableTree::AddTable(wxString & tableName, bool virtualTable, bool tmp)
                                               MyObject(MY_VIRTUAL_GEOMETRY,
                                                        tableName,
                                                        col->GetName())));
+          } else if (col->IsGPKGGeometry() == true)
+            {
+              SetItemData(item2,
+                          (wxTreeItemData *) (new
+                                              MyObject(MY_VIRTUAL_GPKG_GEOMETRY,
+                                                       tableName,
+                                                       col->GetName())));
           } else
             SetItemData(item2,
                         (wxTreeItemData *) (new
@@ -605,12 +890,16 @@ void MyTableTree::AddTable(wxString & tableName, bool virtualTable, bool tmp)
   while (idx)
     {
       indexInfo = idx->GetName();
-      if (indexInfo.StartsWith(wxT("sqlite_autoindex_")) == true)
+      if (idx->ContainsOnlyPrimaryKeyColumns(MainFrame->GetSqlite(), indexInfo,
+                                             list.GetFirstColumn()) == true)
         {
-          item2 = AppendItem(item, wxT("PrimaryKey"), 19);
-          MainFrame->GetPrimaryKeyFields(indexInfo, item2);
-          ok_pk = true;
-          break;
+          if (indexInfo.StartsWith(wxT("sqlite_autoindex_")))
+            {
+              item2 = AppendItem(item, wxT("PrimaryKey"), 19);
+              MainFrame->GetPrimaryKeyFields(indexInfo, item2);
+              ok_pk = true;
+              break;
+            }
         }
       idx = idx->GetNext();
     }
@@ -672,23 +961,41 @@ void MyTableTree::AddTable(wxString & tableName, bool virtualTable, bool tmp)
     }
 }
 
-void MyTableTree::AddView(wxString & viewName, bool tmp)
+void MyTableTree::AddView(wxString & viewName, bool geometry, bool tmp)
 {
 //
 // appends a view to the TREE list
+//
+  wxTreeItemId item;
+  wxTreeItemData *data;
+  int icon = 9;
+  if (tmp == true)
+    icon = 15;
+  wxTreeItemId rootNode = GetRootNode(viewName);
+  data = (wxTreeItemData *) (new MyObject(MY_VIEW, viewName, tmp));
+  item = AppendItem(rootNode, viewName, icon, -1, data);
+  if (geometry == true)
+    SetItemImage(item, 12);
+  AppendItem(item, wxT("placeholder"), 0);
+}
+
+void MyTableTree::ExpandView(wxTreeItemId & item)
+{
+//
+// expands a TreeItem of the View Type
+//
   MyViewInfo list;
   MyColumnInfo *col;
   MyTriggerInfo *trgr;
-  wxTreeItemId item;
   wxTreeItemId item2;
   wxString columnInfo;
   wxString triggerInfo;
   int icon = 9;
-  if (tmp == true)
-    icon = 15;
-  wxTreeItemId rootNode = GetRootNode(viewName);
-  item = AppendItem(rootNode, viewName, icon);
-  SetItemData(item, (wxTreeItemData *) (new MyObject(MY_VIEW, viewName, tmp)));
+  MyObject *obj = (MyObject *) GetItemData(item);
+  if (obj == NULL)
+    return;
+  wxString viewName = obj->GetName();
+
   MainFrame->GetViewColumns(viewName, &list);
   MainFrame->GetViewTriggers(viewName, &list);
   col = list.GetFirst();
@@ -697,7 +1004,6 @@ void MyTableTree::AddView(wxString & viewName, bool tmp)
       columnInfo = col->GetName();
       if (col->IsGeometry() == true)
         {
-          SetItemImage(item, 12);
           if (col->IsGeometryIndex() == true)
             icon = 7;
           else if (col->IsMbrCache() == true)
@@ -748,35 +1054,67 @@ void MyTableTree::AddView(wxString & viewName, bool tmp)
 
 void MyTableTree::AddTable(wxString & dbAlias,
                            wxString & tableName, bool virtualTable,
-                           RootNodes * nodes)
+                           bool geometry, RootNodes * nodes)
 {
 //
 // appends a table to the TREE list [ATTACHED DB]
 //
+  wxTreeItemId item;
+  wxTreeItemId item2;
+  wxTreeItemData *data;
+  bool isCoverage = false;
+  bool isTileData = false;
+  int icon = 1;
+  if (virtualTable == true)
+    icon = 8;
+  if (geometry == true)
+    {
+      if (virtualTable == false)
+        icon = 10;
+      else
+        icon = 13;
+    }
+  wxTreeItemId rootNode =
+    GetAltRootNode(tableName, nodes, &isCoverage, &isTileData);
+  if (isTileData == true)
+    icon = 23;
+  if (virtualTable == true)
+    data =
+      (wxTreeItemData *) (new MyObject(MY_VTABLE, true, dbAlias, tableName));
+  else if (isTileData == true)
+    data =
+      (wxTreeItemData *) (new MyObject(MY_TILE_DATA, true, dbAlias, tableName));
+  else
+    data =
+      (wxTreeItemData *) (new
+                          MyObject(MY_TABLE, true, dbAlias, tableName,
+                                   isCoverage));
+  item = AppendItem(rootNode, tableName, icon, -1, data);
+  AppendItem(item, wxT("placeholder"), 0);
+}
+
+void MyTableTree::ExpandAttachedTable(wxTreeItemId & item)
+{
+//
+// expands a TreeItem of the TABLE type (ATTACHED DB)
+//
   MyTableInfo list;
   MyColumnInfo *col;
   MyIndexInfo *idx;
   MyTriggerInfo *trgr;
-  wxTreeItemId item;
   wxTreeItemId item2;
   wxString columnInfo;
   wxString indexInfo;
   wxString triggerInfo;
-  int icon = 1;
-  if (virtualTable == true)
-    icon = 8;
-  wxTreeItemId rootNode = GetRootNode(tableName, nodes);
-  item = AppendItem(rootNode, tableName, icon);
-  if (virtualTable == true)
-    SetItemData(item,
-                (wxTreeItemData *) (new
-                                    MyObject(MY_VTABLE, true, dbAlias,
-                                             tableName)));
-  else
-    SetItemData(item,
-                (wxTreeItemData *) (new
-                                    MyObject(MY_TABLE, true, dbAlias,
-                                             tableName)));
+  MyObject *obj = (MyObject *) GetItemData(item);
+  if (obj == NULL)
+    return;
+  wxString tableName = obj->GetName();
+  wxString dbAlias = obj->GetDbAlias();
+  bool virtualTable = false;
+  if (obj->GetType() == MY_VTABLE)
+    virtualTable = true;
+
   MainFrame->GetTableColumns(dbAlias, tableName, &list);
   MainFrame->GetTableIndices(dbAlias, tableName, &list);
   MainFrame->GetTableTriggers(dbAlias, tableName, &list);
@@ -788,12 +1126,8 @@ void MyTableTree::AddTable(wxString & dbAlias,
         icon = 2;
       else
         {
-          if (col->IsGeometry() == true)
+          if (col->IsGeometry() == true || col->IsGPKGGeometry() == true)
             {
-              if (virtualTable == false)
-                SetItemImage(item, 10);
-              else
-                SetItemImage(item, 13);
               if (col->IsGeometryIndex() == true)
                 icon = 7;
               else if (col->IsMbrCache() == true)
@@ -814,6 +1148,13 @@ void MyTableTree::AddTable(wxString & dbAlias,
                                               MyObject(MY_VIRTUAL_GEOMETRY,
                                                        tableName,
                                                        col->GetName())));
+          } else if (col->IsGPKGGeometry() == true)
+            {
+              SetItemData(item2,
+                          (wxTreeItemData *) (new
+                                              MyObject(MY_VIRTUAL_GPKG_GEOMETRY,
+                                                       tableName,
+                                                       col->GetName())));
           } else
             SetItemData(item2,
                         (wxTreeItemData *) (new
@@ -923,32 +1264,48 @@ void MyTableTree::AddTable(wxString & dbAlias,
 }
 
 void MyTableTree::AddView(wxString & dbAlias,
-                          wxString & viewName, RootNodes * nodes)
+                          wxString & viewName, bool geometry, RootNodes * nodes)
 {
 //
 // appends a view to the TREE list [ATTACHED DB]
+//
+  wxTreeItemId item;
+  wxTreeItemId item2;
+  wxTreeItemData *data;
+  int icon = 9;
+  if (geometry == true)
+    icon = 12;
+  wxTreeItemId rootNode = GetAltRootNode(viewName, nodes);
+  data = (wxTreeItemData *) (new MyObject(MY_VIEW, true, dbAlias, viewName));
+  item = AppendItem(rootNode, viewName, icon, -1, data);
+  AppendItem(item, wxT("placeholder"), 0);
+}
+
+void MyTableTree::ExpandAttachedView(wxTreeItemId & item)
+{
+//
+// expands a TreeItem of the VIEW type (ATTACHED DB)
+//
   MyViewInfo list;
   MyColumnInfo *col;
   MyTriggerInfo *trgr;
-  wxTreeItemId item;
   wxTreeItemId item2;
   wxString columnInfo;
   wxString triggerInfo;
-  int icon = 9;
-  wxTreeItemId rootNode = GetRootNode(viewName, nodes);
-  item = AppendItem(rootNode, viewName, icon);
-  SetItemData(item,
-              (wxTreeItemData *) (new
-                                  MyObject(MY_VIEW, true, dbAlias, viewName)));
+  MyObject *obj = (MyObject *) GetItemData(item);
+  if (obj == NULL)
+    return;
+  wxString viewName = obj->GetName();
+  wxString dbAlias = obj->GetDbAlias();
   MainFrame->GetViewColumns(dbAlias, viewName, &list);
   MainFrame->GetViewTriggers(dbAlias, viewName, &list);
   col = list.GetFirst();
   while (col)
     {
+      int icon;
       columnInfo = col->GetName();
       if (col->IsGeometry() == true)
         {
-          SetItemImage(item, 12);
           if (col->IsGeometryIndex() == true)
             icon = 7;
           else if (col->IsMbrCache() == true)
@@ -1004,6 +1361,7 @@ void MyTableTree::OnSelChanged(wxTreeEvent & event)
 //
   wxTreeItemId item = event.GetItem();
   if (item == Root || item == RootUserData || item == RootTopologies
+      || item == RootRasterCoverages || item == RootVectorCoverages
       || item == RootStyling || item == RootIsoMetadata || item == RootMetadata
       || item == RootInternal || item == RootSpatialIndex)
     return;
@@ -1018,9 +1376,8 @@ void MyTableTree::OnRightClick(wxTreeEvent & event)
 //
 // right click on some node [mouse action]
 //
-  wxMenu *menu = new wxMenu();
+  wxMenu menu;
   wxMenuItem *menuItem;
-  wxString title;
   bool table = false;
   bool canEdit = false;
   bool view = false;
@@ -1032,6 +1389,7 @@ void MyTableTree::OnRightClick(wxTreeEvent & event)
   bool view_geometry = false;
   bool virtual_column = false;
   bool virtual_geometry = false;
+  bool virtual_gpkg_geometry = false;
   bool index = false;
   bool trigger = false;
   bool attached_db = false;
@@ -1041,55 +1399,302 @@ void MyTableTree::OnRightClick(wxTreeEvent & event)
   wxTreeItemId item = event.GetItem();
   SelectItem(item);
   wxPoint pt = event.GetPoint();
+  if (item == RootRasterCoverages)
+    {
+      CurrentItem = wxTreeItemId();
+      menuItem = new wxMenuItem(&menu, Tree_Refresh, wxT("&Refresh"));
+      menu.Append(menuItem);
+#ifndef OMIT_RL2EXTRA           // only if RasterLite2 extended support is enabled
+      menu.AppendSeparator();
+      menuItem =
+        new wxMenuItem(&menu, Tree_CreateRasterCoverage,
+                       wxT("Create New &Raster Coverage"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem =
+        new wxMenuItem(&menu, Tree_UpdateRasterExtentAll,
+                       wxT("Update Raster &Coverages Extent"));
+      menu.Append(menuItem);
+#endif // end OMIT_RL2EXTRA conditional
+      PopupMenu(&menu, pt);
+      return;
+    }
+  if (item == RootVectorCoverages)
+    {
+      CurrentItem = wxTreeItemId();
+      menuItem = new wxMenuItem(&menu, Tree_Refresh, wxT("&Refresh"));
+      menu.Append(menuItem);
+#ifndef OMIT_RL2EXTRA           // only if RasterLite2 extended support is enabled
+      menu.AppendSeparator();
+      menuItem =
+        new wxMenuItem(&menu, Tree_VectorRegister,
+                       wxT("Register New &Vector Coverage"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem =
+        new wxMenuItem(&menu, Tree_UpdateVectorExtentAll,
+                       wxT("Update Vector &Coverages Extent"));
+      menu.Append(menuItem);
+#endif // end OMIT_RL2EXTRA conditional
+      PopupMenu(&menu, pt);
+      return;
+    }
+  if (item == RootStyling)
+    {
+      CurrentItem = wxTreeItemId();
+      menuItem = new wxMenuItem(&menu, Tree_Refresh, wxT("&Refresh"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+
+#ifndef OMIT_RL2EXTRA           // only if RasterLite2 extended support is enabled
+      wxMenu *externalMenu = new wxMenu();
+      menuItem =
+        new wxMenuItem(externalMenu, Tree_RegisterExternalGraphic,
+                       wxT("&Register New External Graphic"));
+      externalMenu->Append(menuItem);
+      if (MainFrame->IsSecurityLevelRelaxed() != true)
+        menuItem->Enable(false);
+      menuItem =
+        new wxMenuItem(externalMenu, Tree_UnregisterExternalGraphic,
+                       wxT("&Unregister External Graphic"));
+      externalMenu->Append(menuItem);
+      menu.AppendSubMenu(externalMenu, wxT("External &Graphics"));
+      wxMenu *fontMenu = new wxMenu();
+      menuItem =
+        new wxMenuItem(fontMenu, Tree_RegisterTextFont,
+                       wxT("&Register New Text Font"));
+      fontMenu->Append(menuItem);
+      if (MainFrame->IsSecurityLevelRelaxed() != true)
+        menuItem->Enable(false);
+      menuItem =
+        new wxMenuItem(fontMenu, Tree_UnregisterTextFont,
+                       wxT("&Unregister Text Font"));
+      fontMenu->Append(menuItem);
+      menu.AppendSubMenu(fontMenu, wxT("Text &Fonts"));
+      wxMenu *styleMenu = new wxMenu();
+      wxMenu *rasterMenu = new wxMenu();
+      menuItem =
+        new wxMenuItem(rasterMenu, Tree_NewRasterStyle,
+                       wxT("Add New SLD/SE &Raster Style"));
+      rasterMenu->Append(menuItem);
+      if (MainFrame->IsSecurityLevelRelaxed() != true)
+        menuItem->Enable(false);
+      menuItem =
+        new wxMenuItem(rasterMenu, Tree_ReloadRasterStyle,
+                       wxT("Reload SLD/SE Raster &Style"));
+      rasterMenu->Append(menuItem);
+      if (MainFrame->IsSecurityLevelRelaxed() != true)
+        menuItem->Enable(false);
+      menuItem =
+        new wxMenuItem(rasterMenu, Tree_UnregisterRasterStyle,
+                       wxT("&Unregister SLD/SE Raster Style"));
+      rasterMenu->Append(menuItem);
+      styleMenu->AppendSubMenu(rasterMenu, wxT("SLD/SE &Raster Styles"));
+      styleMenu->AppendSeparator();
+      wxMenu *vectorMenu = new wxMenu();
+      menuItem =
+        new wxMenuItem(vectorMenu, Tree_NewVectorStyle,
+                       wxT("Add New SLD/SE &Vector Style"));
+      vectorMenu->Append(menuItem);
+      if (MainFrame->IsSecurityLevelRelaxed() != true)
+        menuItem->Enable(false);
+      menuItem =
+        new wxMenuItem(vectorMenu, Tree_ReloadVectorStyle,
+                       wxT("Reload SLD/SE Vector &Style"));
+      vectorMenu->Append(menuItem);
+      if (MainFrame->IsSecurityLevelRelaxed() != true)
+        menuItem->Enable(false);
+      menuItem =
+        new wxMenuItem(vectorMenu, Tree_UnregisterVectorStyle,
+                       wxT("&Unregister SLD/SE Vector Style"));
+      vectorMenu->Append(menuItem);
+      styleMenu->AppendSubMenu(vectorMenu, wxT("SLD/SE &Vector Styles"));
+      menu.AppendSubMenu(styleMenu, wxT("&SLD/SE &Styles"));
+      wxMenu *toolsMenu = new wxMenu();
+      wxMenu *rasterSymbolizerMenu = new wxMenu();
+      menuItem =
+        new wxMenuItem(rasterSymbolizerMenu, Tree_RasterSymbolizerContrast,
+                       wxT("&Contrast Enhancement"));
+      rasterSymbolizerMenu->Append(menuItem);
+      menuItem =
+        new wxMenuItem(rasterSymbolizerMenu, Tree_RasterSymbolizerChannelRgb,
+                       wxT("Channel Selection [&false-colors]"));
+      rasterSymbolizerMenu->Append(menuItem);
+      menuItem =
+        new wxMenuItem(rasterSymbolizerMenu, Tree_RasterSymbolizerChannelGray,
+                       wxT("Channel Selection [single &gray band]"));
+      rasterSymbolizerMenu->Append(menuItem);
+      menuItem =
+        new wxMenuItem(rasterSymbolizerMenu, Tree_RasterSymbolizerCategorize,
+                       wxT("Color Map: &Categorize"));
+      rasterSymbolizerMenu->Append(menuItem);
+      menuItem =
+        new wxMenuItem(rasterSymbolizerMenu, Tree_RasterSymbolizerInterpolate,
+                       wxT("Color Map: &Interpolate"));
+      rasterSymbolizerMenu->Append(menuItem);
+      menuItem =
+        new wxMenuItem(rasterSymbolizerMenu, Tree_RasterSymbolizerShadedRelief,
+                       wxT("Shaded Relief (&brightness only)"));
+      rasterSymbolizerMenu->Append(menuItem);
+      menuItem =
+        new wxMenuItem(rasterSymbolizerMenu, Tree_RasterSymbolizerMonochrome,
+                       wxT("Recolored &Monochrome"));
+      rasterSymbolizerMenu->Append(menuItem);
+      toolsMenu->AppendSubMenu(rasterSymbolizerMenu,
+                               wxT("Raster&Symbolizer tools"));
+      toolsMenu->AppendSeparator();
+      wxMenu *vectorSymbolizerMenu = new wxMenu();
+      menuItem =
+        new wxMenuItem(vectorSymbolizerMenu, Tree_SimplePointSymbolizer,
+                       wxT("Simple &Point Symbolizer"));
+      vectorSymbolizerMenu->Append(menuItem);
+      menuItem =
+        new wxMenuItem(vectorSymbolizerMenu, Tree_SimpleLineSymbolizer,
+                       wxT("Simple &Line Symbolizer"));
+      vectorSymbolizerMenu->Append(menuItem);
+      menuItem =
+        new wxMenuItem(vectorSymbolizerMenu, Tree_SimplePolygonSymbolizer,
+                       wxT("Simple Pol&ygon Symbolizer"));
+      vectorSymbolizerMenu->Append(menuItem);
+      menuItem =
+        new wxMenuItem(vectorSymbolizerMenu, Tree_SimpleTextSymbolizer,
+                       wxT("Simple &Text Symbolizer"));
+      vectorSymbolizerMenu->Append(menuItem);
+      toolsMenu->AppendSubMenu(vectorSymbolizerMenu,
+                               wxT("VectorS&ymbolizer tools"));
+      menu.AppendSubMenu(toolsMenu, wxT("SLD/SE &Tools"));
+      menu.AppendSeparator();
+#endif // end OMIT_RL2EXTRA conditional
+
+      menuItem =
+        new wxMenuItem(&menu, Tree_UpdateLayerStatisticsAll,
+                       wxT("Update Layer &Statistics"));
+      menu.Append(menuItem);
+      PopupMenu(&menu, pt);
+      return;
+    }
   if (item == Root || item == RootUserData || item == RootTopologies
-      || item == RootStyling || item == RootIsoMetadata || item == RootMetadata
+      || item == RootIsoMetadata || item == RootMetadata
       || item == RootInternal || item == RootSpatialIndex)
     {
       CurrentItem = wxTreeItemId();
-      menuItem = new wxMenuItem(menu, Tree_Refresh, wxT("&Refresh"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_Refresh, wxT("&Refresh"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_QueryViewComposer,
+        new wxMenuItem(&menu, Tree_QueryViewComposer,
                        wxT("Query/View &Composer"));
       menuItem->SetBitmap(wxBitmap(composer_xpm));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_NewTable, wxT("Create New &Table"));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_NewView, wxT("Create New &View"));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_NewTable, wxT("Create New &Table"));
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_NewView, wxT("Create New &View"));
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_UpdateLayerStatisticsAll,
+        new wxMenuItem(&menu, Tree_UpdateLayerStatisticsAll,
                        wxT("Update Layer &Statistics"));
-      menu->Append(menuItem);
-      PopupMenu(menu, pt);
+      menu.Append(menuItem);
+      PopupMenu(&menu, pt);
       return;
     }
   MyObject *obj = (MyObject *) GetItemData(item);
   if (obj == NULL)
     {
       CurrentItem = wxTreeItemId();
-      menuItem = new wxMenuItem(menu, Tree_Refresh, wxT("&Refresh"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem =
-        new wxMenuItem(menu, Tree_QueryViewComposer,
-                       wxT("Query/View &Composer"));
-      menuItem->SetBitmap(wxBitmap(composer_xpm));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_NewTable, wxT("Create New &Table"));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_NewView, wxT("Create New &View"));
-      menu->Append(menuItem);
-      PopupMenu(menu, pt);
+      menuItem = new wxMenuItem(&menu, Tree_Refresh, wxT("&Refresh"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      if (GetItemImage(event.GetItem()) == 22)
+        {
+          // this is a Raster Coverage
+#ifndef OMIT_RL2EXTRA           // only if RasterLite2 extended support is enabled
+          menuItem =
+            new wxMenuItem(&menu, Tree_ImportRaster,
+                           wxT("Import &Raster file(s)"));
+          menu.Append(menuItem);
+          if (MainFrame->IsSecurityLevelRelaxed() != true)
+            menuItem->Enable(false);
+          menuItem =
+            new wxMenuItem(&menu, Tree_Pyramidize,
+                           wxT("Build &Pyramids (by Section)"));
+          menu.Append(menuItem);
+          menuItem =
+            new wxMenuItem(&menu, Tree_PyramidizeMonolithic,
+                           wxT("Build Pyramids (&Monolithic)"));
+          menu.Append(menuItem);
+          menuItem =
+            new wxMenuItem(&menu, Tree_DePyramidize, wxT("&Remove Pyramids"));
+          menu.Append(menuItem);
+          menuItem =
+            new wxMenuItem(&menu, Tree_RasterDrop,
+                           wxT("&Drop Raster Coverage"));
+          menu.Append(menuItem);
+          menuItem =
+            new wxMenuItem(&menu, Tree_UpdateRasterExtent,
+                           wxT("Update Raster &Coverage Extent"));
+          menu.Append(menuItem);
+          menu.AppendSeparator();
+          menuItem =
+            new wxMenuItem(&menu, Tree_SldSeRasterStyles,
+                           wxT("Supported SLD/SE Raster &Styles"));
+          menu.Append(menuItem);
+          menuItem =
+            new wxMenuItem(&menu, Tree_Raster_SRIDs, wxT("&Alternative SRIDs"));
+          menu.Append(menuItem);
+          menuItem =
+            new wxMenuItem(&menu, Tree_Raster_Keywords, wxT("&Keywords"));
+          menu.Append(menuItem);
+#endif // end OMIT_RL2EXTRA
+          CurrentRasterCoverageName = GetItemText(event.GetItem());
+      } else if (GetItemImage(event.GetItem()) == 24)
+        {
+          // this is a Vector Coverage
+#ifndef OMIT_RL2EXTRA           // only if RasterLite2 extended support is enabled
+          menuItem =
+            new wxMenuItem(&menu, Tree_VectorUnregister,
+                           wxT("&Unregister Vector Coverage"));
+          menu.Append(menuItem);
+          menuItem =
+            new wxMenuItem(&menu, Tree_UpdateVectorExtent,
+                           wxT("Update Vector &Coverage Extent"));
+          menu.Append(menuItem);
+          menu.AppendSeparator();
+          menuItem =
+            new wxMenuItem(&menu, Tree_SldSeVectorStyles,
+                           wxT("Supported SLD/SE Vector &Styles"));
+          menu.Append(menuItem);
+          menuItem =
+            new wxMenuItem(&menu, Tree_Vector_SRIDs, wxT("&Alternative SRIDs"));
+          menu.Append(menuItem);
+          menuItem =
+            new wxMenuItem(&menu, Tree_Vector_Keywords, wxT("&Keywords"));
+          menu.Append(menuItem);
+#endif // end OMIT_RL2EXTRA
+          CurrentVectorCoverageName = GetItemText(event.GetItem());
+      } else
+        {
+          menuItem =
+            new wxMenuItem(&menu, Tree_QueryViewComposer,
+                           wxT("Query/View &Composer"));
+          menuItem->SetBitmap(wxBitmap(composer_xpm));
+          menu.Append(menuItem);
+          menu.AppendSeparator();
+          menuItem =
+            new wxMenuItem(&menu, Tree_NewTable, wxT("Create New &Table"));
+          menu.Append(menuItem);
+          menuItem =
+            new wxMenuItem(&menu, Tree_NewView, wxT("Create New &View"));
+          menu.Append(menuItem);
+        }
+      PopupMenu(&menu, pt);
       return;
     }
   switch (obj->GetType())
     {
       case MY_VTABLE:
       case MY_TABLE:
+      case MY_TILE_DATA:
         table = true;
         break;
       case MY_VIEW:
@@ -1118,6 +1723,9 @@ void MyTableTree::OnRightClick(wxTreeEvent & event)
       case MY_VIRTUAL_COLUMN:
         virtual_column = true;
         break;
+      case MY_VIRTUAL_GPKG_GEOMETRY:
+        virtual_gpkg_geometry = true;
+        break;
       case MY_VIRTUAL_GEOMETRY:
         virtual_geometry = true;
         break;
@@ -1130,117 +1738,125 @@ void MyTableTree::OnRightClick(wxTreeEvent & event)
         attached_db = true;
         break;
     };
-  if (obj->GetType() == MY_TABLE)
+  if (obj->GetType() == MY_TABLE && obj->IsCoverage() == false)
     canEdit = true;
   CurrentItem = item;
-  menuItem = new wxMenuItem(menu, Tree_Refresh, wxT("&Refresh"));
-  menu->Append(menuItem);
+  menuItem = new wxMenuItem(&menu, Tree_Refresh, wxT("&Refresh"));
+  menu.Append(menuItem);
   if (table == true)
     {
       if (obj->IsAttached() == true)
         {
           wxString title =
             wxT("Table: ") + obj->GetDbAlias() + wxT(".") + obj->GetName();
-          menu->SetTitle(title);
-          menu->AppendSeparator();
-          menuItem = new wxMenuItem(menu, Tree_Select, wxT("&Query table"));
-          menu->Append(menuItem);
-          menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show columns"));
-          menu->Append(menuItem);
+          menu.SetTitle(title);
+          menu.AppendSeparator();
+          menuItem = new wxMenuItem(&menu, Tree_Select, wxT("&Query table"));
+          menu.Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Tree_Show, wxT("&Show columns"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_ShowSql, wxT("&Show CREATE statement"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_ShowSql, wxT("&Show CREATE statement"));
+          menu.Append(menuItem);
       } else
         {
           wxString title = wxT("Table: ") + obj->GetName();
-          menu->SetTitle(title);
-          menu->AppendSeparator();
+          menu.SetTitle(title);
+          menu.AppendSeparator();
           menuItem =
-            new wxMenuItem(menu, Tree_QueryViewComposer,
+            new wxMenuItem(&menu, Tree_QueryViewComposer,
                            wxT("Query/View &Composer"));
           menuItem->SetBitmap(wxBitmap(composer_xpm));
-          menu->Append(menuItem);
-          menu->AppendSeparator();
+          menu.Append(menuItem);
+          menu.AppendSeparator();
           menuItem =
-            new wxMenuItem(menu, Tree_NewTable, wxT("Create New &Table"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_NewTable, wxT("Create New &Table"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_NewView, wxT("Create New &View"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_NewView, wxT("Create New &View"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_UpdateLayerStatistics,
+            new wxMenuItem(&menu, Tree_UpdateLayerStatistics,
                            wxT("Update Layer &Statistics"));
-          menu->Append(menuItem);
-          menu->AppendSeparator();
+          menu.Append(menuItem);
+          menu.AppendSeparator();
           if (canEdit == true)
             {
               menuItem =
-                new wxMenuItem(menu, Tree_Edit, wxT("&Edit table rows"));
-              menu->Append(menuItem);
+                new wxMenuItem(&menu, Tree_Edit, wxT("&Edit table rows"));
+              menu.Append(menuItem);
           } else
             {
-              menuItem = new wxMenuItem(menu, Tree_Select, wxT("&Query table"));
-              menu->Append(menuItem);
+              if (obj->GetType() == MY_TILE_DATA)
+                menuItem =
+                  new wxMenuItem(&menu, Tree_SelectTiles, wxT("&Query table"));
+              else
+                menuItem =
+                  new wxMenuItem(&menu, Tree_Select, wxT("&Query table"));
+              menu.Append(menuItem);
             }
-          menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show columns"));
-          menu->Append(menuItem);
-          menuItem =
-            new wxMenuItem(menu, Tree_ShowSql, wxT("&Show CREATE statement"));
-          menu->Append(menuItem);
-          menu->AppendSeparator();
-          wxMenu *maintenanceMenu = new wxMenu();
-          menuItem =
-            new wxMenuItem(maintenanceMenu, Tree_NewColumn,
-                           wxT("Add New &Column"));
-          maintenanceMenu->Append(menuItem);
-          menuItem =
-            new wxMenuItem(maintenanceMenu, Tree_Rename, wxT("&Rename table"));
-          maintenanceMenu->Append(menuItem);
-          menuItem =
-            new wxMenuItem(maintenanceMenu, Tree_Drop, wxT("&Drop table"));
-          maintenanceMenu->Append(menuItem);
-          maintenanceMenu->AppendSeparator();
-          menuItem =
-            new wxMenuItem(maintenanceMenu, Tree_NewIndex,
-                           wxT("Create New &Index"));
-          maintenanceMenu->Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Tree_Show, wxT("&Show columns"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(maintenanceMenu, Tree_NewTrigger,
-                           wxT("Create New &Trigger"));
-          maintenanceMenu->Append(menuItem);
-          if (obj->GetType() == MY_TABLE)
+            new wxMenuItem(&menu, Tree_ShowSql, wxT("&Show CREATE statement"));
+          menu.Append(menuItem);
+          if (obj->IsCoverage() != true)
             {
-              maintenanceMenu->AppendSeparator();
-              menuItem =
-                new wxMenuItem(maintenanceMenu, Tree_CheckDuplicates,
-                               wxT("Check &Duplicate rows"));
-              maintenanceMenu->Append(menuItem);
-              menuItem =
-                new wxMenuItem(maintenanceMenu, Tree_RemoveDuplicates,
-                               wxT("Remove Duplicate rows"));
+              if (obj->GetType() == MY_VTABLE)
+                {
+                  menu.AppendSeparator();
+                  menuItem =
+                    new wxMenuItem(&menu, Tree_Drop, wxT("&Drop table"));
+                  menu.Append(menuItem);
+                  menu.AppendSeparator();
+              } else
+                {
+                  menu.AppendSeparator();
+                  wxMenu *maintenanceMenu = new wxMenu();
+                  menuItem =
+                    new wxMenuItem(maintenanceMenu, Tree_NewColumn,
+                                   wxT("Add New &Column"));
+                  maintenanceMenu->Append(menuItem);
+                  menuItem =
+                    new wxMenuItem(maintenanceMenu, Tree_Rename,
+                                   wxT("&Rename table"));
+                  maintenanceMenu->Append(menuItem);
+                  menuItem =
+                    new wxMenuItem(maintenanceMenu, Tree_Drop,
+                                   wxT("&Drop table"));
+                  maintenanceMenu->Append(menuItem);
+                  maintenanceMenu->AppendSeparator();
+                  menuItem =
+                    new wxMenuItem(maintenanceMenu, Tree_NewIndex,
+                                   wxT("Create New &Index"));
+                  maintenanceMenu->Append(menuItem);
+                  menuItem =
+                    new wxMenuItem(maintenanceMenu, Tree_NewTrigger,
+                                   wxT("Create New &Trigger"));
+                  maintenanceMenu->Append(menuItem);
+                  menu.AppendSubMenu(maintenanceMenu, wxT("&Maintenance"));
+                  menu.AppendSeparator();
+                }
             }
-          maintenanceMenu->Append(menuItem);
-          menu->AppendSubMenu(maintenanceMenu, wxT("&Maintenance"));
-          menu->AppendSeparator();
           menuItem =
-            new wxMenuItem(menu, Tree_DumpTxtTab, wxT("Export as &Txt/Tab"));
-          menu->Append(menuItem);
-          menuItem = new wxMenuItem(menu, Tree_DumpCsv, wxT("Export as &CSV"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_DumpTxtTab, wxT("Export as &Txt/Tab"));
+          menu.Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Tree_DumpCsv, wxT("Export as &CSV"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_DumpHtml, wxT("Export as &HTML"));
-          menu->Append(menuItem);
-          menuItem = new wxMenuItem(menu, Tree_DumpDif, wxT("Export as &DIF"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_DumpHtml, wxT("Export as &HTML"));
+          menu.Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Tree_DumpDif, wxT("Export as &DIF"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_DumpSylk, wxT("Export as &SYLK"));
-          menu->Append(menuItem);
-          menuItem = new wxMenuItem(menu, Tree_DumpDbf, wxT("Export as &DBF"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_DumpSylk, wxT("Export as &SYLK"));
+          menu.Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Tree_DumpDbf, wxT("Export as &DBF"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_DumpPostGIS,
+            new wxMenuItem(&menu, Tree_DumpPostGIS,
                            wxT("SQL Dump for &PostGIS"));
-          menu->Append(menuItem);
+          menu.Append(menuItem);
         }
     }
   if (view == true)
@@ -1249,448 +1865,485 @@ void MyTableTree::OnRightClick(wxTreeEvent & event)
         {
           wxString title =
             wxT("View: ") + obj->GetDbAlias() + wxT(".") + obj->GetName();
-          menu->SetTitle(title);
-          menu->AppendSeparator();
-          menuItem = new wxMenuItem(menu, Tree_Select, wxT("&Query view"));
-          menu->Append(menuItem);
-          menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show columns"));
-          menu->Append(menuItem);
+          menu.SetTitle(title);
+          menu.AppendSeparator();
+          menuItem = new wxMenuItem(&menu, Tree_Select, wxT("&Query view"));
+          menu.Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Tree_Show, wxT("&Show columns"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_ShowSql, wxT("&Show CREATE statement"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_ShowSql, wxT("&Show CREATE statement"));
+          menu.Append(menuItem);
       } else
         {
           wxString title = wxT("View: ") + obj->GetName();
-          menu->SetTitle(title);
-          menu->AppendSeparator();
+          menu.SetTitle(title);
+          menu.AppendSeparator();
           menuItem =
-            new wxMenuItem(menu, Tree_QueryViewComposer,
+            new wxMenuItem(&menu, Tree_QueryViewComposer,
                            wxT("Query/View &Composer"));
           menuItem->SetBitmap(wxBitmap(composer_xpm));
-          menu->Append(menuItem);
-          menu->AppendSeparator();
+          menu.Append(menuItem);
+          menu.AppendSeparator();
           menuItem =
-            new wxMenuItem(menu, Tree_NewTable, wxT("Create New &Table"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_NewTable, wxT("Create New &Table"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_NewView, wxT("Create New &View"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_NewView, wxT("Create New &View"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_UpdateLayerStatistics,
+            new wxMenuItem(&menu, Tree_UpdateLayerStatistics,
                            wxT("Update Layer &Statistics"));
-          menu->Append(menuItem);
-          menu->AppendSeparator();
-          menuItem = new wxMenuItem(menu, Tree_Select, wxT("&Query view"));
-          menu->Append(menuItem);
-          menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show columns"));
-          menu->Append(menuItem);
+          menu.Append(menuItem);
+          menu.AppendSeparator();
+          menuItem = new wxMenuItem(&menu, Tree_Select, wxT("&Query view"));
+          menu.Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Tree_Show, wxT("&Show columns"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_ShowSql, wxT("&Show CREATE statement"));
-          menu->Append(menuItem);
-          menu->AppendSeparator();
-          menuItem = new wxMenuItem(menu, Tree_Drop, wxT("&Drop view"));
-          menu->Append(menuItem);
-          menu->AppendSeparator();
+            new wxMenuItem(&menu, Tree_ShowSql, wxT("&Show CREATE statement"));
+          menu.Append(menuItem);
+          menu.AppendSeparator();
+          menuItem = new wxMenuItem(&menu, Tree_Drop, wxT("&Drop view"));
+          menu.Append(menuItem);
+          menu.AppendSeparator();
           menuItem =
-            new wxMenuItem(menu, Tree_DumpTxtTab, wxT("Export as &Txt/Tab"));
-          menu->Append(menuItem);
-          menuItem = new wxMenuItem(menu, Tree_DumpCsv, wxT("Export as &CSV"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_DumpTxtTab, wxT("Export as &Txt/Tab"));
+          menu.Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Tree_DumpCsv, wxT("Export as &CSV"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_DumpHtml, wxT("Export as &HTML"));
-          menu->Append(menuItem);
-          menuItem = new wxMenuItem(menu, Tree_DumpDif, wxT("Export as &DIF"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_DumpHtml, wxT("Export as &HTML"));
+          menu.Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Tree_DumpDif, wxT("Export as &DIF"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_DumpSylk, wxT("Export as &SYLK"));
-          menu->Append(menuItem);
-          menuItem = new wxMenuItem(menu, Tree_DumpDbf, wxT("Export as &DBF"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_DumpSylk, wxT("Export as &SYLK"));
+          menu.Append(menuItem);
+          menuItem = new wxMenuItem(&menu, Tree_DumpDbf, wxT("Export as &DBF"));
+          menu.Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_DumpPostGIS,
+            new wxMenuItem(&menu, Tree_DumpPostGIS,
                            wxT("SQL Dump for &PostGIS"));
-          menu->Append(menuItem);
+          menu.Append(menuItem);
         }
     }
   if (column == true)
     {
       wxString title =
         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
-      menu->SetTitle(title);
-      menu->AppendSeparator();
+      menu.SetTitle(title);
+      menu.AppendSeparator();
       if (MainFrame->IsPrimaryKey(obj->GetName(), obj->GetColumn()) == false)
         {
-          menuItem = new wxMenuItem(menu, Tree_DropColumn, wxT("&Drop Column"));
-          menu->Append(menuItem);
           menuItem =
-            new wxMenuItem(menu, Tree_RenameColumn, wxT("&Rename Column"));
-          menu->Append(menuItem);
-          menu->AppendSeparator();
+            new wxMenuItem(&menu, Tree_DropColumn, wxT("&Drop Column"));
+          menu.Append(menuItem);
+          menuItem =
+            new wxMenuItem(&menu, Tree_RenameColumn, wxT("&Rename Column"));
+          menu.Append(menuItem);
+          menu.AppendSeparator();
         }
       menuItem =
-        new wxMenuItem(menu, Tree_CheckGeometry, wxT("&Check geometries"));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_MapPreview, wxT("&Map Preview"));
+        new wxMenuItem(&menu, Tree_CheckGeometry, wxT("&Check geometries"));
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_MapPreview, wxT("&Map Preview"));
       menuItem->SetBitmap(wxBitmap(map_preview_xpm));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_Extent, wxT("&Extent"));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_Extent, wxT("&Extent"));
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_UpdateLayerStatistics,
+        new wxMenuItem(&menu, Tree_UpdateLayerStatistics,
                        wxT("Update Layer &Statistics"));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_SetSrid, wxT("&Set SRID"));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_SetSrid, wxT("&Set SRID"));
+      menu.Append(menuItem);
       if (metadata == true)
         {
-          menu->AppendSeparator();
+          menu.AppendSeparator();
           menuItem =
-            new wxMenuItem(menu, Tree_Recover, wxT("&Recover geometry column"));
-          menu->Append(menuItem);
+            new wxMenuItem(&menu, Tree_Recover,
+                           wxT("&Recover geometry column"));
+          menu.Append(menuItem);
         }
-      menu->AppendSeparator();
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_ColumnStats, wxT("&Statistic snapshot"));
+        new wxMenuItem(&menu, Tree_ColumnStats, wxT("&Statistic snapshot"));
       menuItem->SetBitmap(wxBitmap(statistics_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
     }
   if (view_column == true)
     {
       wxString title =
         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
-      menu->SetTitle(title);
-      menu->AppendSeparator();
+      menu.SetTitle(title);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_ColumnStats, wxT("&Statistic snapshot"));
+        new wxMenuItem(&menu, Tree_ColumnStats, wxT("&Statistic snapshot"));
       menuItem->SetBitmap(wxBitmap(statistics_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
     }
   if (virtual_column == true)
     {
       wxString title =
         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
-      menu->SetTitle(title);
-      menu->AppendSeparator();
+      menu.SetTitle(title);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_ColumnStats, wxT("&Statistic snapshot"));
+        new wxMenuItem(&menu, Tree_ColumnStats, wxT("&Statistic snapshot"));
       menuItem->SetBitmap(wxBitmap(statistics_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
     }
   if (geometry == true)
     {
       wxString title =
         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
-      menu->SetTitle(title);
-      menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show Spatial Metadata"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.SetTitle(title);
+      menuItem = new wxMenuItem(&menu, Tree_DropColumn, wxT("&Drop Column"));
+      menu.Append(menuItem);
+      menuItem =
+        new wxMenuItem(&menu, Tree_RenameColumn, wxT("&Rename Column"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_CheckGeom, wxT("&LWGEOM Check geometries"));
+        new wxMenuItem(&menu, Tree_Show, wxT("&Show Spatial Metadata"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem =
+        new wxMenuItem(&menu, Tree_CheckGeom, wxT("&LWGEOM Check geometries"));
       menuItem->SetBitmap(wxBitmap(checkgeom_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_SaneGeom, wxT("&LWGEOM Sanitize geometries"));
+        new wxMenuItem(&menu, Tree_SaneGeom,
+                       wxT("&LWGEOM Sanitize geometries"));
       menuItem->SetBitmap(wxBitmap(sanegeom_xpm));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_GisLayerAuth,
+        new wxMenuItem(&menu, Tree_GisLayerAuth,
                        wxT("&GIS layer authorizations"));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_CheckGeometry, wxT("&Check geometries"));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_Extent, wxT("&Extent"));
-      menu->Append(menuItem);
+        new wxMenuItem(&menu, Tree_CheckGeometry, wxT("&Check geometries"));
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_Extent, wxT("&Extent"));
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_UpdateLayerStatistics,
+        new wxMenuItem(&menu, Tree_UpdateLayerStatistics,
                        wxT("Update Layer &Statistics"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_SpatialIndex, wxT("&Build Spatial Index"));
+        new wxMenuItem(&menu, Tree_SpatialIndex, wxT("&Build Spatial Index"));
       menuItem->SetBitmap(wxBitmap(spatialidx_xpm));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_MbrCache, wxT("Build &MBR cache"));
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_MbrCache, wxT("Build &MBR cache"));
       menuItem->SetBitmap(wxBitmap(mbrcache_xpm));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_RebuildTriggers,
+        new wxMenuItem(&menu, Tree_RebuildTriggers,
                        wxT("Rebuild Geometry &Triggers"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_DumpShp, wxT("Export as &Shapefile"));
+        new wxMenuItem(&menu, Tree_DumpShp, wxT("Export as &Shapefile"));
       menuItem->SetBitmap(wxBitmap(dumpshp_xpm));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_DumpKml, wxT("Export as &KML"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_DumpKml, wxT("Export as &KML"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_ElementaryGeoms,
+        new wxMenuItem(&menu, Tree_ElementaryGeoms,
                        wxT("&separating elementary Geometries"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_MalformedGeometries,
+        new wxMenuItem(&menu, Tree_MalformedGeometries,
                        wxT("&Malformed geometries"));
       menuItem->SetBitmap(wxBitmap(malformed_geoms_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_RepairPolygons, wxT("&Repair Polygons"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_MapPreview, wxT("&Map Preview"));
+        new wxMenuItem(&menu, Tree_RepairPolygons, wxT("&Repair Polygons"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_MapPreview, wxT("&Map Preview"));
       menuItem->SetBitmap(wxBitmap(map_preview_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
     }
   if (geometry_index == true)
     {
       wxString title =
         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
-      menu->SetTitle(title);
-      menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show Spatial Metadata"));
-      menu->Append(menuItem);
+      menu.SetTitle(title);
+      menuItem = new wxMenuItem(&menu, Tree_DropColumn, wxT("&Drop Column"));
+      menu.Append(menuItem);
+      menuItem =
+        new wxMenuItem(&menu, Tree_RenameColumn, wxT("&Rename Column"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_GisLayerAuth,
+        new wxMenuItem(&menu, Tree_Show, wxT("&Show Spatial Metadata"));
+      menu.Append(menuItem);
+      menuItem =
+        new wxMenuItem(&menu, Tree_GisLayerAuth,
                        wxT("&GIS layer authorizations"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_CheckGeom, wxT("&LWGEOM Check geometries"));
+        new wxMenuItem(&menu, Tree_CheckGeom, wxT("&LWGEOM Check geometries"));
       menuItem->SetBitmap(wxBitmap(checkgeom_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_SaneGeom, wxT("&LWGEOM Sanitize geometries"));
+        new wxMenuItem(&menu, Tree_SaneGeom,
+                       wxT("&LWGEOM Sanitize geometries"));
       menuItem->SetBitmap(wxBitmap(sanegeom_xpm));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_CheckGeometry, wxT("&Check geometries"));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_Extent, wxT("&Extent"));
-      menu->Append(menuItem);
+        new wxMenuItem(&menu, Tree_CheckGeometry, wxT("&Check geometries"));
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_Extent, wxT("&Extent"));
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_UpdateLayerStatistics,
+        new wxMenuItem(&menu, Tree_UpdateLayerStatistics,
                        wxT("Update Layer &Statistics"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_SpatialIndex, wxT("&Remove Spatial Index"));
+        new wxMenuItem(&menu, Tree_SpatialIndex, wxT("&Remove Spatial Index"));
       menuItem->SetBitmap(wxBitmap(kill_spindex_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_CheckSpatialIndex,
+        new wxMenuItem(&menu, Tree_CheckSpatialIndex,
                        wxT("&Check Spatial Index"));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_RecoverSpatialIndex,
+        new wxMenuItem(&menu, Tree_RecoverSpatialIndex,
                        wxT("&Recover Spatial Index"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_RebuildTriggers,
+        new wxMenuItem(&menu, Tree_RebuildTriggers,
                        wxT("Rebuild Geometry &Triggers"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_DumpShp, wxT("Export as &Shapefile"));
+        new wxMenuItem(&menu, Tree_DumpShp, wxT("Export as &Shapefile"));
       menuItem->SetBitmap(wxBitmap(dumpshp_xpm));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_DumpKml, wxT("Export as &KML"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_DumpKml, wxT("Export as &KML"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_ElementaryGeoms,
+        new wxMenuItem(&menu, Tree_ElementaryGeoms,
                        wxT("&separating elementary Geometries"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_MalformedGeometries,
+        new wxMenuItem(&menu, Tree_MalformedGeometries,
                        wxT("&Malformed geometries"));
       menuItem->SetBitmap(wxBitmap(malformed_geoms_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_RepairPolygons, wxT("&Repair Polygons"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_MapPreview, wxT("&Map Preview"));
+        new wxMenuItem(&menu, Tree_RepairPolygons, wxT("&Repair Polygons"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_MapPreview, wxT("&Map Preview"));
       menuItem->SetBitmap(wxBitmap(map_preview_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
     }
   if (geometry_cached == true)
     {
       wxString title =
         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
-      menu->SetTitle(title);
-      menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show Spatial Metadata"));
-      menu->Append(menuItem);
+      menu.SetTitle(title);
+      menuItem = new wxMenuItem(&menu, Tree_DropColumn, wxT("&Drop Column"));
+      menu.Append(menuItem);
+      menuItem =
+        new wxMenuItem(&menu, Tree_RenameColumn, wxT("&Rename Column"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_GisLayerAuth,
+        new wxMenuItem(&menu, Tree_Show, wxT("&Show Spatial Metadata"));
+      menu.Append(menuItem);
+      menuItem =
+        new wxMenuItem(&menu, Tree_GisLayerAuth,
                        wxT("&GIS layer authorizations"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_CheckGeom, wxT("&LWGEOM Check geometries"));
+        new wxMenuItem(&menu, Tree_CheckGeom, wxT("&LWGEOM Check geometries"));
       menuItem->SetBitmap(wxBitmap(checkgeom_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_SaneGeom, wxT("&LWGEOM Sanitize geometries"));
+        new wxMenuItem(&menu, Tree_SaneGeom,
+                       wxT("&LWGEOM Sanitize geometries"));
       menuItem->SetBitmap(wxBitmap(sanegeom_xpm));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_CheckGeometry, wxT("&Check geometries"));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_Extent, wxT("&Extent"));
-      menu->Append(menuItem);
+        new wxMenuItem(&menu, Tree_CheckGeometry, wxT("&Check geometries"));
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_Extent, wxT("&Extent"));
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_UpdateLayerStatistics,
+        new wxMenuItem(&menu, Tree_UpdateLayerStatistics,
                        wxT("Update Layer &Statistics"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_MbrCache, wxT("&Remove MBR cache"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_MbrCache, wxT("&Remove MBR cache"));
       menuItem->SetBitmap(wxBitmap(kill_spindex_xpm));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_RebuildTriggers,
+        new wxMenuItem(&menu, Tree_RebuildTriggers,
                        wxT("Rebuild Geometry &Triggers"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_DumpShp, wxT("Export as &Shapefile"));
+        new wxMenuItem(&menu, Tree_DumpShp, wxT("Export as &Shapefile"));
       menuItem->SetBitmap(wxBitmap(dumpshp_xpm));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_DumpKml, wxT("Export as &KML"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_DumpKml, wxT("Export as &KML"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_ElementaryGeoms,
+        new wxMenuItem(&menu, Tree_ElementaryGeoms,
                        wxT("&separating elementary Geometries"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_MalformedGeometries,
+        new wxMenuItem(&menu, Tree_MalformedGeometries,
                        wxT("&Malformed geometries"));
       menuItem->SetBitmap(wxBitmap(malformed_geoms_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_RepairPolygons, wxT("&Repair Polygons"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_MapPreview, wxT("&Map Preview"));
+        new wxMenuItem(&menu, Tree_RepairPolygons, wxT("&Repair Polygons"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_MapPreview, wxT("&Map Preview"));
       menuItem->SetBitmap(wxBitmap(map_preview_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
     }
   if (view_geometry == true)
     {
       wxString title =
         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
-      menu->SetTitle(title);
-      menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show Spatial Metadata"));
-      menu->Append(menuItem);
+      menu.SetTitle(title);
+      menuItem =
+        new wxMenuItem(&menu, Tree_Show, wxT("&Show Spatial Metadata"));
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_GisLayerAuth,
+        new wxMenuItem(&menu, Tree_GisLayerAuth,
                        wxT("&GIS layer authorizations"));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_Extent, wxT("&Extent"));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_Extent, wxT("&Extent"));
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_UpdateLayerStatistics,
+        new wxMenuItem(&menu, Tree_UpdateLayerStatistics,
                        wxT("Update Layer &Statistics"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_DumpShp, wxT("Export as &Shapefile"));
+        new wxMenuItem(&menu, Tree_DumpShp, wxT("Export as &Shapefile"));
       menuItem->SetBitmap(wxBitmap(dumpshp_xpm));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_DumpKml, wxT("Export as &KML"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_DumpKml, wxT("Export as &KML"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_ElementaryGeoms,
+        new wxMenuItem(&menu, Tree_ElementaryGeoms,
                        wxT("&separating elementary Geometries"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_MalformedGeometries,
+        new wxMenuItem(&menu, Tree_MalformedGeometries,
                        wxT("&Malformed geometries"));
       menuItem->SetBitmap(wxBitmap(malformed_geoms_xpm));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_MapPreview, wxT("&Map Preview"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_MapPreview, wxT("&Map Preview"));
       menuItem->SetBitmap(wxBitmap(map_preview_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
     }
   if (virtual_geometry == true)
     {
       wxString title =
         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
-      menu->SetTitle(title);
-      menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show Spatial Metadata"));
-      menu->Append(menuItem);
+      menu.SetTitle(title);
       menuItem =
-        new wxMenuItem(menu, Tree_GisLayerAuth,
+        new wxMenuItem(&menu, Tree_Show, wxT("&Show Spatial Metadata"));
+      menu.Append(menuItem);
+      menuItem =
+        new wxMenuItem(&menu, Tree_GisLayerAuth,
                        wxT("&GIS layer authorizations"));
-      menu->Append(menuItem);
-      menuItem = new wxMenuItem(menu, Tree_Extent, wxT("&Extent"));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
+      menuItem = new wxMenuItem(&menu, Tree_Extent, wxT("&Extent"));
+      menu.Append(menuItem);
       menuItem =
-        new wxMenuItem(menu, Tree_UpdateLayerStatistics,
+        new wxMenuItem(&menu, Tree_UpdateLayerStatistics,
                        wxT("Update Layer &Statistics"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_DumpKml, wxT("Export as &KML"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_DumpKml, wxT("Export as &KML"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_ElementaryGeoms,
+        new wxMenuItem(&menu, Tree_ElementaryGeoms,
                        wxT("&separating elementary Geometries"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
+      menu.Append(menuItem);
+      menu.AppendSeparator();
       menuItem =
-        new wxMenuItem(menu, Tree_MalformedGeometries,
+        new wxMenuItem(&menu, Tree_MalformedGeometries,
                        wxT("&Malformed geometries"));
       menuItem->SetBitmap(wxBitmap(malformed_geoms_xpm));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_MapPreview, wxT("&Map Preview"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_MapPreview, wxT("&Map Preview"));
+      menuItem->SetBitmap(wxBitmap(map_preview_xpm));
+      menu.Append(menuItem);
+    }
+  if (virtual_gpkg_geometry == true)
+    {
+      wxString title =
+        wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
+      menu.SetTitle(title);
+      menuItem = new wxMenuItem(&menu, Tree_MapPreview, wxT("&Map Preview"));
       menuItem->SetBitmap(wxBitmap(map_preview_xpm));
-      menu->Append(menuItem);
+      menu.Append(menuItem);
     }
   if (index == true)
     {
       wxString title = wxT("Index: ") + obj->GetName();
-      menu->SetTitle(title);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show index"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_Drop, wxT("&Drop index"));
-      menu->Append(menuItem);
+      menu.SetTitle(title);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_Show, wxT("&Show index"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_Drop, wxT("&Drop index"));
+      menu.Append(menuItem);
     }
   if (trigger == true)
     {
       wxString title = wxT("Trigger: ") + obj->GetName();
-      menu->SetTitle(title);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show trigger"));
-      menu->Append(menuItem);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_Drop, wxT("&Drop trigger"));
-      menu->Append(menuItem);
+      menu.SetTitle(title);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_Show, wxT("&Show trigger"));
+      menu.Append(menuItem);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_Drop, wxT("&Drop trigger"));
+      menu.Append(menuItem);
     }
   if (attached_db == true)
     {
       wxString title = wxT("Attached DB: ") + obj->GetName();
-      menu->SetTitle(title);
-      menu->AppendSeparator();
-      menuItem = new wxMenuItem(menu, Tree_Detach, wxT("&Detach Database"));
-      menu->Append(menuItem);
+      menu.SetTitle(title);
+      menu.AppendSeparator();
+      menuItem = new wxMenuItem(&menu, Tree_Detach, wxT("&Detach Database"));
+      menu.Append(menuItem);
     }
-  PopupMenu(menu, pt);
+  PopupMenu(&menu, pt);
 }
 
 void MyTableTree::OnCmdQueryViewComposer(wxCommandEvent & WXUNUSED(event))
@@ -1793,6 +2446,7 @@ void MyTableTree::OnCmdSelect(wxCommandEvent & WXUNUSED(event))
 // menu event - examining table rows required
 //
   wxString sql;
+  wxString dummy;
   char xname[1024];
   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
   if (obj == NULL)
@@ -1803,7 +2457,32 @@ void MyTableTree::OnCmdSelect(wxCommandEvent & WXUNUSED(event))
   strcpy(xname, obj->GetName().ToUTF8());
   MainFrame->DoubleQuotedSql(xname);
   sql += wxString::FromUTF8(xname);
-  MainFrame->SetSql(sql, true);
+  MainFrame->SetSql(sql, true, false, dummy, true);
+}
+
+void MyTableTree::OnCmdSelectTiles(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - examining table rows required
+//
+  wxString tile_data_table;
+  wxString sql;
+  char xname[1024];
+  MyObject *obj = (MyObject *) GetItemData(CurrentItem);
+  if (obj == NULL)
+    return;
+  if (obj->GetType() == MY_TILE_DATA)
+    {
+      wxString table = obj->GetName();
+      table.EndsWith(wxT("_tile_data"), &tile_data_table);
+    }
+  sql = wxT("SELECT * FROM ");
+  if (obj->IsAttached() == true)
+    sql += obj->GetDbAlias() + wxT(".");
+  strcpy(xname, obj->GetName().ToUTF8());
+  MainFrame->DoubleQuotedSql(xname);
+  sql += wxString::FromUTF8(xname);
+  MainFrame->SetSql(sql, true, true, tile_data_table, true);
 }
 
 void MyTableTree::OnCmdShow(wxCommandEvent & WXUNUSED(event))
@@ -1909,17 +2588,15 @@ void MyTableTree::OnCmdDrop(wxCommandEvent & WXUNUSED(event))
   char *errMsg = NULL;
   int ret;
   wxString name;
+  char xprefix[1024];
   char xname[1024];
   sqlite3 *sqlite = MainFrame->GetSqlite();
   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
+  wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, Tree_RefreshDeferred);
   if (obj == NULL)
     return;
   if (obj->GetType() == MY_TABLE)
     {
-      sql = wxT("DROP TABLE IF EXISTS ");
-      strcpy(xname, obj->GetName().ToUTF8());
-      MainFrame->DoubleQuotedSql(xname);
-      sql += wxString::FromUTF8(xname);
       msg = wxT("Do you really intend to drop the Table named: ");
       msg += obj->GetName();
       msg += wxT("\n[and any other related object] ?");
@@ -1929,20 +2606,12 @@ void MyTableTree::OnCmdDrop(wxCommandEvent & WXUNUSED(event))
       msg = wxT("Do you really intend to drop the VirtualTable named: ");
       msg += obj->GetName();
       msg += wxT(" ?");
-      sql = wxT("DROP TABLE IF EXISTS ");
-      strcpy(xname, obj->GetName().ToUTF8());
-      MainFrame->DoubleQuotedSql(xname);
-      sql += wxString::FromUTF8(xname);
     }
   if (obj->GetType() == MY_VIEW)
     {
       msg = wxT("Do you really intend to drop the View named: ");
       msg += obj->GetName();
       msg += wxT(" ?");
-      sql = wxT("DROP VIEW IF EXISTS ");
-      strcpy(xname, obj->GetName().ToUTF8());
-      MainFrame->DoubleQuotedSql(xname);
-      sql += wxString::FromUTF8(xname);
     }
   if (obj->GetType() == MY_INDEX)
     {
@@ -1972,18 +2641,33 @@ void MyTableTree::OnCmdDrop(wxCommandEvent & WXUNUSED(event))
   ::wxBeginBusyCursor();
   if (obj->GetType() == MY_TABLE)
     {
+      strcpy(xprefix, obj->GetDbAlias().ToUTF8());
       strcpy(xname, obj->GetName().ToUTF8());
-      gaiaDropTable(sqlite, xname);
+      if (strlen(xprefix) == 0)
+        gaiaDropTable(sqlite, xname);
+      else
+        gaiaDropTableEx2(sqlite, xprefix, xname, 1);
+      goto done;
     }
   if (obj->GetType() == MY_VTABLE)
     {
+      strcpy(xprefix, obj->GetDbAlias().ToUTF8());
       strcpy(xname, obj->GetName().ToUTF8());
-      gaiaDropTable(sqlite, xname);
+      if (strlen(xprefix) == 0)
+        gaiaDropTable(sqlite, xname);
+      else
+        gaiaDropTableEx2(sqlite, xprefix, xname, 1);
+      goto done;
     }
   if (obj->GetType() == MY_VIEW)
     {
+      strcpy(xprefix, obj->GetDbAlias().ToUTF8());
       strcpy(xname, obj->GetName().ToUTF8());
-      gaiaDropTable(sqlite, xname);
+      if (strlen(xprefix) == 0)
+        gaiaDropTable(sqlite, xname);
+      else
+        gaiaDropTableEx2(sqlite, xprefix, xname, 1);
+      goto done;
     }
   ret = sqlite3_exec(sqlite, sql.ToUTF8(), NULL, NULL, &errMsg);
   if (ret != SQLITE_OK)
@@ -1994,11 +2678,13 @@ void MyTableTree::OnCmdDrop(wxCommandEvent & WXUNUSED(event))
       ::wxEndBusyCursor();
       goto rollback;
     }
+done:
   ::wxEndBusyCursor();
   wxMessageBox(wxT("Selected object '") + obj->GetName() +
                wxT("' was successfully removed"), wxT("spatialite_gui"),
                wxOK | wxICON_INFORMATION, this);
-  MainFrame->InitTableTree();
+  // appending a delayed event so to really update the Tree
+  AddPendingEvent(evt);
   return;
 rollback:
   ret = sqlite3_exec(sqlite, "ROLLBACK", NULL, NULL, &errMsg);
@@ -2071,15 +2757,29 @@ void MyTableTree::OnCmdDetachDB(wxCommandEvent & WXUNUSED(event))
           sqlite3_free(errMsg);
           return;
         }
-      MainFrame->InitTableTree();
+      // appending a delayed event so to really update the Tree
+      wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, Tree_RefreshDeferred);
+      AddPendingEvent(evt);
     }
 }
 
 void MyTableTree::OnCmdRefresh(wxCommandEvent & WXUNUSED(event))
 {
 //
+// menu event - refreshing the Tree (via deferrend event)
+//
+  wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, Tree_RefreshDeferred);
+  AddPendingEvent(evt);
+}
+
+void MyTableTree::OnRefreshDeferred(wxCommandEvent & WXUNUSED(event))
+{
+//
 // menu event - refreshing the Tree
 //
+// safe deferred event processing so to avoid any attempt from wxWidgets
+// itself to continue using invalid Tree Items (already being destroied)
+//
   MainFrame->InitTableTree();
 }
 
@@ -2303,7 +3003,14 @@ void MyTableTree::OnCmdCheckSpatialIndex(wxCommandEvent & WXUNUSED(event))
         }
       sqlite3_free_table(results);
       ::wxEndBusyCursor();
-      if (retval)
+      if (retval < 0)
+        wxMessageBox(wxT("Spatial Index idx_") + obj->GetName() +
+                     wxT("_") + obj->GetColumn() +
+                     wxT(" is badly damaged.\n\n") +
+                     wxT
+                     ("a physical column named \"rowid\" exists shadowing the real ROWID"),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else if (retval)
         wxMessageBox(wxT("Spatial Index idx_") + obj->GetName() +
                      wxT("_") + obj->GetColumn() +
                      wxT(" is valid and consistent"), wxT("spatialite_gui"),
@@ -2371,7 +3078,14 @@ void MyTableTree::OnCmdRecoverSpatialIndex(wxCommandEvent & WXUNUSED(event))
         }
       sqlite3_free_table(results);
       ::wxEndBusyCursor();
-      if (retval)
+      if (retval < 0)
+        wxMessageBox(wxT("Spatial Index idx_") + obj->GetName() +
+                     wxT("_") + obj->GetColumn() +
+                     wxT(" is badly damaged.\n\n") +
+                     wxT
+                     ("a physical column named \"rowid\" exists shadowing the real ROWID"),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else if (retval)
         wxMessageBox(wxT("Spatial Index idx_") + obj->GetName() +
                      wxT("_") + obj->GetColumn() +
                      wxT(" was succesfully recovered"), wxT("spatialite_gui"),
@@ -2464,7 +3178,9 @@ void MyTableTree::OnCmdSpatialIndex(wxCommandEvent & WXUNUSED(event))
                    wxT("_") + obj->GetColumn() +
                    wxT(" was successfully created"), wxT("spatialite_gui"),
                    wxOK | wxICON_INFORMATION, this);
-      MainFrame->InitTableTree();
+// appending a delayed event so to really update the Tree
+      wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, Tree_RefreshDeferred);
+      AddPendingEvent(evt);
   } else if (obj->GetType() == MY_GEOMETRY_INDEX)
     {
       // dropping the Spatial Index
@@ -2552,7 +3268,9 @@ void MyTableTree::OnCmdSpatialIndex(wxCommandEvent & WXUNUSED(event))
                    wxT("_") + obj->GetColumn() +
                    wxT(" was successfully removed"), wxT("spatialite_gui"),
                    wxOK | wxICON_INFORMATION, this);
-      MainFrame->InitTableTree();
+      // appending a delayed event so to really update the Tree
+      wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, Tree_RefreshDeferred);
+      AddPendingEvent(evt);
     }
   return;
 rollback:
@@ -2652,7 +3370,9 @@ void MyTableTree::OnCmdMbrCache(wxCommandEvent & WXUNUSED(event))
                    wxT("_") + obj->GetColumn() +
                    wxT(" was successfully created"), wxT("spatialite_gui"),
                    wxOK | wxICON_INFORMATION, this);
-      MainFrame->InitTableTree();
+      // appending a delayed event so to really update the Tree
+      wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, Tree_RefreshDeferred);
+      AddPendingEvent(evt);
   } else if (obj->GetType() == MY_GEOMETRY_CACHED)
     {
       // dropping the MBR cache
@@ -2740,7 +3460,9 @@ void MyTableTree::OnCmdMbrCache(wxCommandEvent & WXUNUSED(event))
                    wxT("_") + obj->GetColumn() +
                    wxT(" was successfully removed"), wxT("spatialite_gui"),
                    wxOK | wxICON_INFORMATION, this);
-      MainFrame->InitTableTree();
+      // appending a delayed event so to really update the Tree
+      wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, Tree_RefreshDeferred);
+      AddPendingEvent(evt);
     }
   return;
 rollback:
@@ -2802,47 +3524,48 @@ void MyTableTree::OnCmdGisLayerAuth(wxCommandEvent & WXUNUSED(event))
   char *value;
   bool readOnly = false;
   bool hidden = false;
+  bool is_table = false;
   GisLayerAuthDialog dlg;
   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
   if (obj == NULL)
     return;
   if (obj->GetType() == MY_GEOMETRY || obj->GetType() == MY_GEOMETRY_INDEX
-      || obj->GetType() == MY_GEOMETRY_CACHED
-      || obj->GetType() == MY_VIEW_GEOMETRY)
+      || obj->GetType() == MY_GEOMETRY_CACHED)
     {
-      sql = wxT("SELECT read_only, hidden FROM geometry_columns AS a ");
+      sql = wxT("SELECT b.read_only, b.hidden FROM geometry_columns AS a ");
       sql += wxT("LEFT JOIN geometry_columns_auth AS b ON ");
       sql += wxT("(Lower(a.f_table_name) = Lower(b.f_table_name) AND ");
       sql += wxT("Lower(a.f_geometry_column) = Lower(b.f_geometry_column)) ");
-      sql += wxT("WHERE Lower(f_table_name) = Lower('");
+      sql += wxT("WHERE Lower(a.f_table_name) = Lower('");
       sql += obj->GetName();
-      sql += wxT("') AND Lower(f_geometry_column) = Lower('");
+      sql += wxT("') AND Lower(a.f_geometry_column) = Lower('");
       sql += obj->GetColumn();
       sql += wxT("')");
+      is_table = true;
     }
   if (obj->GetType() == MY_VIEW_GEOMETRY_INDEX
       || obj->GetType() == MY_VIEW_GEOMETRY_CACHED
-      || obj->GetType() == MY_VIRTUAL_GEOMETRY)
+      || obj->GetType() == MY_VIEW_GEOMETRY)
     {
-      sql = wxT("SELECT read_only, hidden FROM views_geometry_columns ");
-      sql += wxT("LEFT JOIN geometry_columns_auth AS x ON ");
-      sql += wxT("(Lower(view_name) = Lower(x.f_table_name) AND ");
-      sql += wxT("Lower(view_geometry) = Lower(x.f_geometry_column)) ");
-      sql += wxT("WHERE Lower(view_name) = Lower('");
+      sql = wxT("SELECT 1, b.hidden FROM views_geometry_columns AS a ");
+      sql += wxT("LEFT JOIN views_geometry_columns_auth AS b ON ");
+      sql += wxT("(Lower(a.view_name) = Lower(b.view_name) AND ");
+      sql += wxT("Lower(a.view_geometry) = Lower(b.view_geometry)) ");
+      sql += wxT("WHERE Lower(a.view_name) = Lower('");
       sql += obj->GetName();
-      sql += wxT("') AND Lower(view_geometry) = Lower('");
+      sql += wxT("') AND Lower(a.view_geometry) = Lower('");
       sql += obj->GetColumn();
       sql += wxT("')");
     }
   if (obj->GetType() == MY_VIRTUAL_GEOMETRY)
     {
-      sql = wxT("SELECT read_only, hidden FROM virts_geometry_columns ");
-      sql += wxT("LEFT JOIN geometry_columns_auth ON ");
-      sql += wxT("(Lower(virt_name) = Lower(f_table_name) AND ");
-      sql += wxT("Lower(virt_geometry) = Lower(f_geometry_column)) ");
-      sql += wxT("WHERE Lower(virt_name) = Lower('");
+      sql = wxT("SELECT 1, b.hidden FROM virts_geometry_columns AS a ");
+      sql += wxT("LEFT JOIN virts_geometry_columns_auth AS b ON ");
+      sql += wxT("(Lower(a.virt_name) = Lower(b.virt_name) AND ");
+      sql += wxT("Lower(a.virt_geometry) = Lower(b.virt_geometry)) ");
+      sql += wxT("WHERE Lower(a.virt_name) = Lower('");
       sql += obj->GetName();
-      sql += wxT("') AND Lower(virt_geometry) = Lower('");
+      sql += wxT("') AND Lower(a.virt_geometry) = Lower('");
       sql += obj->GetColumn();
       sql += wxT("')");
     }
@@ -2882,23 +3605,58 @@ void MyTableTree::OnCmdGisLayerAuth(wxCommandEvent & WXUNUSED(event))
         }
     }
   sqlite3_free_table(results);
-  dlg.Create(MainFrame, obj->GetName(), obj->GetColumn(), readOnly, hidden);
+  dlg.Create(MainFrame, obj->GetName(), obj->GetColumn(), readOnly, hidden,
+             is_table);
   ret = dlg.ShowModal();
   if (ret == wxID_OK)
     {
-      // updating the GEOMETRY_COLUMNS_AUTH table
-      sql = wxT("INSERT OR REPLACE INTO geometry_columns_auth ");
-      sql += wxT("(f_table_name, f_geometry_column, read_only, hidden) ");
-      sql += wxT("VALUES ('");
-      sql += obj->GetName();
-      sql += wxT("', '");
-      sql += obj->GetColumn();
-      if (dlg.IsHidden() == true)
-        sql += wxT("', 0, 1)");
-      else if (dlg.IsReadOnly() == true)
-        sql += wxT("', 1, 0)");
-      else
-        sql += wxT("', 0, 0)");
+      if (obj->GetType() == MY_GEOMETRY || obj->GetType() == MY_GEOMETRY_INDEX
+          || obj->GetType() == MY_GEOMETRY_CACHED)
+        {
+          // updating the GEOMETRY_COLUMNS_AUTH table
+          sql = wxT("INSERT OR REPLACE INTO geometry_columns_auth ");
+          sql += wxT("(f_table_name, f_geometry_column, read_only, hidden) ");
+          sql += wxT("VALUES (Lower('");
+          sql += obj->GetName();
+          sql += wxT("'), Lower('");
+          sql += obj->GetColumn();
+          if (dlg.IsHidden() == true)
+            sql += wxT("'), 0, 1)");
+          else if (dlg.IsReadOnly() == true)
+            sql += wxT("'), 1, 0)");
+          else
+            sql += wxT("'), 0, 0)");
+        }
+      if (obj->GetType() == MY_VIEW_GEOMETRY_INDEX
+          || obj->GetType() == MY_VIEW_GEOMETRY_CACHED
+          || obj->GetType() == MY_VIEW_GEOMETRY)
+        {
+          // updating the VIEWS_GEOMETRY_COLUMNS_AUTH table
+          sql = wxT("INSERT OR REPLACE INTO views_geometry_columns_auth ");
+          sql += wxT("(view_name, view_geometry, hidden) ");
+          sql += wxT("VALUES (Lower('");
+          sql += obj->GetName();
+          sql += wxT("'), Lower('");
+          sql += obj->GetColumn();
+          if (dlg.IsHidden() == true)
+            sql += wxT("'), 1)");
+          else
+            sql += wxT("'), 0)");
+        }
+      if (obj->GetType() == MY_VIRTUAL_GEOMETRY)
+        {
+          // updating the VIRTS_GEOMETRY_COLUMNS_AUTH table
+          sql = wxT("INSERT OR REPLACE INTO virts_geometry_columns_auth ");
+          sql += wxT("(virt_name, virt_geometry, hidden) ");
+          sql += wxT("VALUES (Lower('");
+          sql += obj->GetName();
+          sql += wxT("'), Lower('");
+          sql += obj->GetColumn();
+          if (dlg.IsHidden() == true)
+            sql += wxT("'), 1)");
+          else
+            sql += wxT("'), 0)");
+        }
       ret =
         sqlite3_exec(MainFrame->GetSqlite(), sql.ToUTF8(), NULL, NULL, &errMsg);
       if (ret != SQLITE_OK)
@@ -3040,6 +3798,62 @@ OnCmdUpdateLayerStatisticsAll(wxCommandEvent & WXUNUSED(event))
   MainFrame->SetSql(sql, true);
 }
 
+void MyTableTree::OnCmdUpdateRasterExtent(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - Updating Raster Coverage Extent
+//
+  wxString coverage = CurrentRasterCoverageName;
+  int pos = CurrentRasterCoverageName.Find('[', true);
+  if (pos != wxNOT_FOUND)
+    coverage = CurrentRasterCoverageName.Left(pos - 1);
+  char *xcov = new char[strlen(coverage.ToUTF8()) + 1];
+  strcpy(xcov, coverage.ToUTF8());
+  char *xsql =
+    sqlite3_mprintf("SELECT SE_UpdateRasterCoverageExtent(%Q, 1)", xcov);
+  delete[]xcov;
+  wxString sql = wxString::FromUTF8(xsql);
+  sqlite3_free(xsql);
+  MainFrame->SetSql(sql, true);
+}
+
+void MyTableTree::OnCmdUpdateRasterExtentAll(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - Updating Raster Coverage Extent [ALL]
+//
+  wxString sql = wxT("SELECT SE_UpdateRasterCoverageExtent(1)");
+  MainFrame->SetSql(sql, true);
+}
+
+void MyTableTree::OnCmdUpdateVectorExtent(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - Updating Vector Coverage Extent
+//
+  wxString coverage = CurrentVectorCoverageName;
+  int pos = CurrentVectorCoverageName.Find('[', true);
+  if (pos != wxNOT_FOUND)
+    coverage = CurrentVectorCoverageName.Left(pos - 1);
+  char *xcov = new char[strlen(coverage.ToUTF8()) + 1];
+  strcpy(xcov, coverage.ToUTF8());
+  char *xsql =
+    sqlite3_mprintf("SELECT SE_UpdateVectorCoverageExtent(%Q, 1)", xcov);
+  delete[]xcov;
+  wxString sql = wxString::FromUTF8(xsql);
+  sqlite3_free(xsql);
+  MainFrame->SetSql(sql, true);
+}
+
+void MyTableTree::OnCmdUpdateVectorExtentAll(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - Updating Vector Coverage Extent [ALL]
+//
+  wxString sql = wxT("SELECT SE_UpdateVectorCoverageExtent(1)");
+  MainFrame->SetSql(sql, true);
+}
+
 void MyTableTree::OnCmdElementaryGeometries(wxCommandEvent & WXUNUSED(event))
 {
 //
@@ -3053,7 +3867,8 @@ void MyTableTree::OnCmdElementaryGeometries(wxCommandEvent & WXUNUSED(event))
       || obj->GetType() == MY_VIEW_GEOMETRY
       || obj->GetType() == MY_VIEW_GEOMETRY_INDEX
       || obj->GetType() == MY_VIEW_GEOMETRY_CACHED
-      || obj->GetType() == MY_VIRTUAL_GEOMETRY)
+      || obj->GetType() == MY_VIRTUAL_GEOMETRY
+      || obj->GetType() == MY_VIRTUAL_GPKG_GEOMETRY)
     {
       ElementaryGeomsDialog dlg;
       dlg.Create(MainFrame, obj->GetName(), obj->GetColumn());
@@ -3073,7 +3888,12 @@ void MyTableTree::OnCmdElementaryGeometries(wxCommandEvent & WXUNUSED(event))
                                               srid, coordDims, spIdx);
           ::wxEndBusyCursor();
           if (ret)
-            MainFrame->InitTableTree();
+            {
+              // appending a delayed event so to really update the Tree
+              wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED,
+                                 Tree_RefreshDeferred);
+              AddPendingEvent(evt);
+            }
         }
     }
 }
@@ -3091,7 +3911,8 @@ void MyTableTree::OnCmdMalformedGeometries(wxCommandEvent & WXUNUSED(event))
       || obj->GetType() == MY_VIEW_GEOMETRY
       || obj->GetType() == MY_VIEW_GEOMETRY_INDEX
       || obj->GetType() == MY_VIEW_GEOMETRY_CACHED
-      || obj->GetType() == MY_VIRTUAL_GEOMETRY)
+      || obj->GetType() == MY_VIRTUAL_GEOMETRY
+      || obj->GetType() == MY_VIRTUAL_GPKG_GEOMETRY)
     {
       bool repair = true;
       if (obj->GetType() == MY_VIEW_GEOMETRY
@@ -4961,8 +5782,8 @@ bool MyTableTree::DropRenameAux1(MyObject * obj, GeomColsList * Geometries,
 }
 
 void MyTableTree::DropRenameAux2(MyObject * obj, GeomColsList * Geometries,
-                                 wxString & aliasTable, wxString & renameSql,
-                                 wxString & dropSql,
+                                 wxString & aliasTable, wxString & new_column,
+                                 wxString & renameSql, wxString & dropSql,
                                  wxString & disableSpatialIdxSql,
                                  wxString & dropSpatialIdxSql,
                                  wxString & createSpatialIdxSql,
@@ -5019,30 +5840,62 @@ void MyTableTree::DropRenameAux2(MyObject * obj, GeomColsList * Geometries,
           MainFrame->DoubleQuotedSql(xname);
           dropSpatialIdxSql += wxString::FromUTF8(xname);
           dropSpatialIdxSql += wxT(";\n");
-          if (pG->IsRTree() == true)
+          wxString name1 = pG->GetGeometryName();
+          wxString name2 = obj->GetColumn();
+          if (name1.CmpNoCase(name2) != 0)
             {
-              // creating an RTree Spatial Index
-              createSpatialIdxSql += wxT("SELECT CreateSpatialIndex('");
-              strcpy(xname, obj->GetName().ToUTF8());
-              MainFrame->CleanSqlString(xname);
-              createSpatialIdxSql += wxString::FromUTF8(xname);
-              createSpatialIdxSql += wxT("', '");
-              strcpy(xname, pG->GetGeometryName().ToUTF8());
-              MainFrame->CleanSqlString(xname);
-              createSpatialIdxSql += wxString::FromUTF8(xname);
-              createSpatialIdxSql += wxT("');\n");
-          } else
+              if (pG->IsRTree() == true)
+                {
+                  // creating an RTree Spatial Index
+                  createSpatialIdxSql += wxT("SELECT CreateSpatialIndex('");
+                  strcpy(xname, obj->GetName().ToUTF8());
+                  MainFrame->CleanSqlString(xname);
+                  createSpatialIdxSql += wxString::FromUTF8(xname);
+                  createSpatialIdxSql += wxT("', '");
+                  strcpy(xname, pG->GetGeometryName().ToUTF8());
+                  MainFrame->CleanSqlString(xname);
+                  createSpatialIdxSql += wxString::FromUTF8(xname);
+                  createSpatialIdxSql += wxT("');\n");
+              } else
+                {
+                  // creating an MbrCache Spatial Index
+                  createSpatialIdxSql += wxT("SELECT CreateMbrCache('");
+                  strcpy(xname, obj->GetName().ToUTF8());
+                  MainFrame->CleanSqlString(xname);
+                  createSpatialIdxSql += wxString::FromUTF8(xname);
+                  createSpatialIdxSql += wxT("', '");
+                  strcpy(xname, pG->GetGeometryName().ToUTF8());
+                  MainFrame->CleanSqlString(xname);
+                  createSpatialIdxSql += wxString::FromUTF8(xname);
+                  createSpatialIdxSql += wxT("');\n");
+                }
+          } else if (new_column.Len() > 0)
             {
-              // creating an MbrCache Spatial Index
-              createSpatialIdxSql += wxT("SELECT CreateMbrCache('");
-              strcpy(xname, obj->GetName().ToUTF8());
-              MainFrame->CleanSqlString(xname);
-              createSpatialIdxSql += wxString::FromUTF8(xname);
-              createSpatialIdxSql += wxT("', '");
-              strcpy(xname, pG->GetGeometryName().ToUTF8());
-              MainFrame->CleanSqlString(xname);
-              createSpatialIdxSql += wxString::FromUTF8(xname);
-              createSpatialIdxSql += wxT("');\n");
+              if (pG->IsRTree() == true)
+                {
+                  // creating an RTree Spatial Index
+                  createSpatialIdxSql += wxT("SELECT CreateSpatialIndex('");
+                  strcpy(xname, obj->GetName().ToUTF8());
+                  MainFrame->CleanSqlString(xname);
+                  createSpatialIdxSql += wxString::FromUTF8(xname);
+                  createSpatialIdxSql += wxT("', '");
+                  strcpy(xname, new_column.ToUTF8());
+                  MainFrame->CleanSqlString(xname);
+                  createSpatialIdxSql += wxString::FromUTF8(xname);
+                  createSpatialIdxSql += wxT("');\n");
+              } else
+                {
+                  // creating an MbrCache Spatial Index
+                  createSpatialIdxSql += wxT("SELECT CreateMbrCache('");
+                  strcpy(xname, obj->GetName().ToUTF8());
+                  MainFrame->CleanSqlString(xname);
+                  createSpatialIdxSql += wxString::FromUTF8(xname);
+                  createSpatialIdxSql += wxT("', '");
+                  strcpy(xname, new_column.ToUTF8());
+                  MainFrame->CleanSqlString(xname);
+                  createSpatialIdxSql += wxString::FromUTF8(xname);
+                  createSpatialIdxSql += wxT("');\n");
+                }
             }
         }
       // discarding a Geometry Column
@@ -5059,7 +5912,8 @@ void MyTableTree::DropRenameAux2(MyObject * obj, GeomColsList * Geometries,
     }
 }
 
-void MyTableTree::DropRenameAux3(MyObject * obj, GeomColsList * Geometries,
+void MyTableTree::DropRenameAux3(MyObject * obj, wxString & new_column,
+                                 GeomColsList * Geometries,
                                  TblIndexList * Index,
                                  wxString & addGeometrySql)
 {
@@ -5085,6 +5939,43 @@ void MyTableTree::DropRenameAux3(MyObject * obj, GeomColsList * Geometries,
   while (pG)
     {
       // adding a Geometry Column
+      wxString name1 = pG->GetGeometryName();
+      wxString name2 = obj->GetColumn();
+      if (name1.CmpNoCase(name2) == 0)
+        {
+          if (new_column.Len() > 0)
+            {
+              addGeometrySql += wxT("SELECT AddGeometryColumn('");
+              strcpy(xname, obj->GetName().ToUTF8());
+              MainFrame->CleanSqlString(xname);
+              addGeometrySql += wxString::FromUTF8(xname);
+              addGeometrySql += wxT("', '");
+              strcpy(xname, new_column.ToUTF8());
+              MainFrame->CleanSqlString(xname);
+              addGeometrySql += wxString::FromUTF8(xname);
+              sprintf(dummy, "', %d", pG->GetSrid());
+              addGeometrySql += wxString::FromUTF8(dummy);
+              addGeometrySql += wxT(", '");
+              addGeometrySql += pG->GetGeometryType();
+              if (pG->GetCoordDims() == wxT('2')
+                  || pG->GetCoordDims() == wxT('3'))
+                {
+                  addGeometrySql += wxT("', ");
+                  addGeometrySql += pG->GetCoordDims();
+              } else
+                {
+                  addGeometrySql += wxT("', '");
+                  addGeometrySql += pG->GetCoordDims();
+                  addGeometrySql += wxT("'");
+                }
+              if (pG->IsNotNull() == false)
+                addGeometrySql += wxT(");\n");
+              else
+                addGeometrySql += wxT(", 1);\n");
+            }
+          pG = pG->GetNext();
+          continue;
+        }
       addGeometrySql += wxT("SELECT AddGeometryColumn('");
       strcpy(xname, obj->GetName().ToUTF8());
       MainFrame->CleanSqlString(xname);
@@ -5198,6 +6089,7 @@ void MyTableTree::OnCmdDropColumn(wxCommandEvent & WXUNUSED(event))
   int columns;
   int i;
   char *errMsg = NULL;
+  wxString new_column;
   wxString sql;
   wxString createSql;
   wxString insertSql;
@@ -5226,13 +6118,14 @@ void MyTableTree::OnCmdDropColumn(wxCommandEvent & WXUNUSED(event))
   wxString name;
   char xname[1024];
   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
+  wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, Tree_RefreshDeferred);
   if (obj == NULL)
     return;
 
   strcpy(column, obj->GetColumn().ToUTF8());
   if (DropRenameAux1(obj, &Geometries, &autoincrement) == false)
     return;
-  DropRenameAux2(obj, &Geometries, aliasTable, renameSql, dropSql,
+  DropRenameAux2(obj, &Geometries, aliasTable, new_column, renameSql, dropSql,
                  disableSpatialIdxSql, dropSpatialIdxSql, createSpatialIdxSql,
                  discardGeometrySql);
 
@@ -5349,7 +6242,7 @@ void MyTableTree::OnCmdDropColumn(wxCommandEvent & WXUNUSED(event))
     }
   sqlite3_free_table(results);
 
-  DropRenameAux3(obj, &Geometries, &Index, addGeometrySql);
+  DropRenameAux3(obj, new_column, &Geometries, &Index, addGeometrySql);
 
 // setting up the Index SQL fragments
   Index.Invalidate(obj->GetColumn());
@@ -5439,7 +6332,8 @@ void MyTableTree::OnCmdDropColumn(wxCommandEvent & WXUNUSED(event))
                wxT("\nwas successfully removed\nfrom the Table ") +
                obj->GetName(), wxT("spatialite_gui"),
                wxOK | wxICON_INFORMATION, this);
-  MainFrame->InitTableTree();
+  // appending a delayed event so to really update the Tree
+  AddPendingEvent(evt);
   return;
 rollback:
   ret = sqlite3_exec(MainFrame->GetSqlite(), "ROLLBACK", NULL, NULL, &errMsg);
@@ -5497,6 +6391,8 @@ void MyTableTree::OnCmdRenameColumn(wxCommandEvent & WXUNUSED(event))
   wxString name;
   char xname[1024];
   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
+  wxCommandEvent evt =
+    wxCommandEvent(wxEVT_COMMAND_MENU_SELECTED, Tree_RefreshDeferred);
   if (obj == NULL)
     return;
 
@@ -5509,7 +6405,7 @@ void MyTableTree::OnCmdRenameColumn(wxCommandEvent & WXUNUSED(event))
   strcpy(column, obj->GetColumn().ToUTF8());
   if (DropRenameAux1(obj, &Geometries, &autoincrement) == false)
     return;
-  DropRenameAux2(obj, &Geometries, aliasTable, renameSql, dropSql,
+  DropRenameAux2(obj, &Geometries, aliasTable, newColumn, renameSql, dropSql,
                  disableSpatialIdxSql, dropSpatialIdxSql, createSpatialIdxSql,
                  discardGeometrySql);
 
@@ -5640,7 +6536,7 @@ void MyTableTree::OnCmdRenameColumn(wxCommandEvent & WXUNUSED(event))
     }
   sqlite3_free_table(results);
 
-  DropRenameAux3(obj, &Geometries, &Index, addGeometrySql);
+  DropRenameAux3(obj, newColumn, &Geometries, &Index, addGeometrySql);
 
 // setting up the Index SQL fragments
   pI = Index.GetFirst();
@@ -5712,8 +6608,6 @@ void MyTableTree::OnCmdRenameColumn(wxCommandEvent & WXUNUSED(event))
   sql += wxT("COMMIT;");
   if (sql.Len() < 1)
     return;
-  char cazzo[8192];
-  strcpy(cazzo, sql.ToUTF8());
   msg = wxT("Do you really intend to rename the Column ");
   msg += obj->GetColumn();
   msg += wxT(" as ");
@@ -5743,7 +6637,8 @@ void MyTableTree::OnCmdRenameColumn(wxCommandEvent & WXUNUSED(event))
                wxT("\nwas successfully renamed as ") + newColumn +
                wxT("\ninto the Table ") + obj->GetName(),
                wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
-  MainFrame->InitTableTree();
+  // appending a delayed event so to really update the Tree
+  AddPendingEvent(evt);
   return;
 rollback:
   ret = sqlite3_exec(MainFrame->GetSqlite(), "ROLLBACK", NULL, NULL, &errMsg);
@@ -5910,102 +6805,33 @@ void MyTableTree::OnCmdRemoveDuplicates(wxCommandEvent & WXUNUSED(event))
 //
 // menu event - Removing Duplicate rows
 //
-  DuplRow value_list;
-  wxString sql;
-  wxString sql2;
-  wxString col_list;
-  wxString params_list;
-  bool first = true;
-  char xname[1024];
-  int count;
-  int pk;
-  int ret;
-  char **results;
-  int rows;
-  int columns;
-  int i;
-  char *errMsg = NULL;
   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
   if (obj == NULL)
     return;
   if (obj->GetType() == MY_TABLE)
     {
-      // extracting the column names (excluding any Primary Key)
-      value_list.SetTable(obj->GetName());
-      sql = wxT("PRAGMA table_info(");
-      strcpy(xname, obj->GetName().ToUTF8());
-      MainFrame->DoubleQuotedSql(xname);
-      sql += wxString::FromUTF8(xname);
-      sql += wxT(")");
-      ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
-                              &rows, &columns, &errMsg);
-      if (ret != SQLITE_OK)
-        {
-          wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
-                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
-          sqlite3_free(errMsg);
-          return;
-        }
-      if (rows < 1)
-        ;
-      else
+      wxString msg;
+      int count = 0;
+      char *table = new char[obj->GetName().Len()];
+      strcpy(table, obj->GetName().ToUTF8());
+      ::wxBeginBusyCursor();
+      remove_duplicated_rows_ex2(MainFrame->GetSqlite(), table, &count, 1);
+      delete[]table;
+      ::wxEndBusyCursor();
+      if (!count)
         {
-          for (i = 1; i <= rows; i++)
-            {
-              strcpy(xname, results[(i * columns) + 1]);
-              pk = atoi(results[(i * columns) + 5]);
-              if (!pk)
-                {
-                  if (first)
-                    first = false;
-                  else
-                    col_list += wxT(", ");
-                  MainFrame->DoubleQuotedSql(xname);
-                  wxString col_name = wxString::FromUTF8(xname);
-                  col_list += col_name;
-                  value_list.Add(col_name);
-                }
-            }
-        }
-      sqlite3_free_table(results);
-      // preparing the SQL statement (identifying duplicated rows)
-      sql = wxT("SELECT Count(*) AS \"[dupl-count]\", ");
-      sql += col_list;
-      sql += wxT("\nFROM ");
-      strcpy(xname, obj->GetName().ToUTF8());
-      MainFrame->DoubleQuotedSql(xname);
-      sql += wxString::FromUTF8(xname);
-      sql += wxT("\nGROUP BY ");
-      sql += col_list;
-      sql += wxT("\nHAVING \"[dupl-count]\" > 1");
-      // preparing the SQL statement [delete]
-      sql2 = wxT("DELETE FROM ");
-      strcpy(xname, obj->GetName().ToUTF8());
-      MainFrame->DoubleQuotedSql(xname);
-      sql2 += wxString::FromUTF8(xname);
-      sql2 += wxT(" WHERE ROWID = ?");
-
-      if (doDeleteDuplicates(sql, sql2, &value_list, &count) == true)
+          msg = wxT("No duplicated rows have been identified on ");
+          msg += obj->GetName();
+          wxMessageBox(msg, wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+      } else
         {
-          if (!count)
-            {
-              strcpy(xname, "No duplicated rows have been identified on ");
-              sql = wxString::FromUTF8(xname);
-              strcpy(xname, obj->GetName().ToUTF8());
-              MainFrame->DoubleQuotedSql(xname);
-              sql += wxString::FromUTF8(xname);
-              wxMessageBox(sql, wxT("spatialite_gui"),
-                           wxOK | wxICON_INFORMATION, this);
-          } else
-            {
-              sprintf(xname, "%d duplicated rows deleted from ", count);
-              sql = wxString::FromUTF8(xname);
-              strcpy(xname, obj->GetName().ToUTF8());
-              MainFrame->DoubleQuotedSql(xname);
-              sql += wxString::FromUTF8(xname);
-              wxMessageBox(sql, wxT("spatialite_gui"),
-                           wxOK | wxICON_INFORMATION, this);
-            }
+          char dummy[128];
+          sprintf(dummy, "%d duplicated rows deleted from ", count);
+          msg = wxString::FromUTF8(dummy);
+          msg += obj->GetName();
+          wxMessageBox(msg, wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
         }
     }
 }
@@ -6056,8 +6882,9 @@ void MyTableTree::OnCmdCheckGeometries(wxCommandEvent & WXUNUSED(event))
       ::wxBeginBusyCursor();
       int n_invalids;
       ret =
-        check_geometry_column(MainFrame->GetSqlite(), xtable, xgeometry,
-                              report_path, NULL, &n_invalids, &err_msg);
+        check_geometry_column_r(MainFrame->GetSpliteInternalCache(),
+                                MainFrame->GetSqlite(), xtable, xgeometry,
+                                report_path, NULL, &n_invalids, &err_msg);
       ::wxEndBusyCursor();
       if (ret == 0)
         {
@@ -6144,9 +6971,10 @@ void MyTableTree::OnCmdSanitizeGeometries(wxCommandEvent & WXUNUSED(event))
       ::wxBeginBusyCursor();
       int n_failures;
       ret =
-        sanitize_geometry_column(MainFrame->GetSqlite(), xtable, xgeometry,
-                                 tmp_prefix, report_path, NULL, NULL, NULL,
-                                 &n_failures, &err_msg);
+        sanitize_geometry_column_r(MainFrame->GetSpliteInternalCache(),
+                                   MainFrame->GetSqlite(), xtable, xgeometry,
+                                   tmp_prefix, report_path, NULL, NULL, NULL,
+                                   &n_failures, &err_msg);
       ::wxEndBusyCursor();
       if (ret == 0)
         {
@@ -6185,457 +7013,775 @@ void MyTableTree::OnCmdSanitizeGeometries(wxCommandEvent & WXUNUSED(event))
     }
 }
 
-bool MyTableTree::doDeleteDuplicates(wxString & sql1, wxString & sql2,
-                                     DuplRow * value_list, int *count)
+void MyTableTree::OnCmdSldSeRasterStyles(wxCommandEvent & WXUNUSED(event))
 {
-// deleting duplicate rows
-  char xsql[8192];
-  sqlite3_stmt *stmt1 = NULL;
-  sqlite3_stmt *stmt2 = NULL;
-  int ret;
-  int xcnt;
-  int cnt = 0;
-  int n_cols;
-  int col_no;
-  char *sql_err = NULL;
-
-  *count = 0;
-  ::wxBeginBusyCursor();
+//
+// menu event - Handling Raster Coverage SLD/SE styles
+//
+  RasterCoverageStylesDialog dlg;
+  dlg.Create(MainFrame, CurrentRasterCoverageName);
+  dlg.ShowModal();
+}
 
-// the complete operation is handled as an unique SQL Transaction 
-  ret = sqlite3_exec(MainFrame->GetSqlite(), "BEGIN", NULL, NULL, &sql_err);
-  if (ret != SQLITE_OK)
+void MyTableTree::OnCmdImportRaster(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - Importing one (or even more) external Raster file(s)
+//
+  int ret;
+  wxString lastDir;
+  wxString path;
+  ImportRasterDialog dlg;
+  wxString suffixList =
+    wxT("Raster files (*.tif;*.jpg;*.jp2;*.asc)|*.tif;*.jpg;*.jp2;*.asc|");
+  suffixList += wxT("TIFF or GeoTIFF image (*.tif)|*.tif|");
+  suffixList += wxT("JPEG image (*.jpg)|*.jpg|");
+  suffixList += wxT("JPEG2000 image (*.jp2)|*.jp2|");
+  suffixList += wxT("ASCII Grid (*.asc)|*.asc|");
+  suffixList += wxT("All files (*.*)|*.*");
+  wxFileDialog fileDialog(this, wxT("Selecting Raster File(s) to be imported"),
+                          wxT(""), wxT(""), suffixList,
+                          wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE,
+                          wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
     {
-      sqlite3_free(sql_err);
-      return false;
-    }
-// preparing the main SELECT statement
-  strcpy(xsql, sql1.ToUTF8());
-  ret =
-    sqlite3_prepare_v2(MainFrame->GetSqlite(), xsql, strlen(xsql), &stmt1,
-                       NULL);
-  if (ret != SQLITE_OK)
-    {
-      sprintf(xsql, "SQL error: %s", sqlite3_errmsg(MainFrame->GetSqlite()));
-      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(xsql),
-                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
-      return false;
-    }
-// preparing the DELETE statement
-  strcpy(xsql, sql2.ToUTF8());
-  ret =
-    sqlite3_prepare_v2(MainFrame->GetSqlite(), xsql, strlen(xsql), &stmt2,
-                       NULL);
-  if (ret != SQLITE_OK)
-    {
-      sprintf(xsql, "SQL error: %s", sqlite3_errmsg(MainFrame->GetSqlite()));
-      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(xsql),
-                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
-      goto error;
+      int count;
+      wxArrayString paths;
+      fileDialog.GetPaths(paths);
+      count = paths.GetCount();
+      path = paths.Item(0);
+      int more = count - 1;
+      if (count >= 2)
+        {
+          path += wxT("\n") + paths.Item(1);
+          more--;
+        }
+      wxFileName file(path);
+      lastDir = file.GetPath();
+      MainFrame->SetLastDirectory(lastDir);
+      if (more > 0)
+        {
+          char dummy[128];
+          sprintf(dummy, "\n(and %d more %s)", more,
+                  (more > 1) ? "files" : "file");
+          path += wxString::FromUTF8(dummy);
+        }
+      wxString title;
+      wxString abstract;
+      wxString sample;
+      wxString pixel;
+      wxString compression;
+      int srid;
+      wxString coverage = CurrentRasterCoverageName;
+      int pos = CurrentRasterCoverageName.Find('[', true);
+      if (pos != wxNOT_FOUND)
+        coverage = CurrentRasterCoverageName.Left(pos - 1);
+      if (MainFrame->DoGetRasterCoverageInfos
+          (coverage, title, abstract, sample, pixel, compression,
+           &srid) == false)
+        return;
+      dlg.Create(MainFrame, coverage, paths, path, title, abstract, sample,
+                 pixel, compression, srid);
+      dlg.ShowModal();
     }
+}
 
-  while (1)
-    {
-      //
-      // fetching the result set rows 
-      //
-      ret = sqlite3_step(stmt1);
-      if (ret == SQLITE_DONE)
-        break;                  // end of result set
-      if (ret == SQLITE_ROW)
+void MyTableTree::OnCmdPyramidize(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - Pyramidize
+//
+  PyramidizeDialog dlg;
+  wxString title;
+  wxString abstract;
+  wxString sample;
+  wxString pixel;
+  wxString compression;
+  int srid;
+  wxString coverage = CurrentRasterCoverageName;
+  int pos = CurrentRasterCoverageName.Find('[', true);
+  if (pos != wxNOT_FOUND)
+    coverage = CurrentRasterCoverageName.Left(pos - 1);
+  if (MainFrame->DoGetRasterCoverageInfos
+      (coverage, title, abstract, sample, pixel, compression, &srid) == false)
+    return;
+  dlg.Create(MainFrame, coverage, title, abstract, sample, pixel, compression);
+  dlg.ShowModal();
+}
+
+void MyTableTree::OnCmdPyramidizeMonolithic(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - PyramidizeMonolithic
+//
+  PyramidizeMonolithicDialog dlg;
+  wxString title;
+  wxString abstract;
+  wxString sample;
+  wxString pixel;
+  wxString compression;
+  int srid;
+  wxString coverage = CurrentRasterCoverageName;
+  int pos = CurrentRasterCoverageName.Find('[', true);
+  if (pos != wxNOT_FOUND)
+    coverage = CurrentRasterCoverageName.Left(pos - 1);
+  if (MainFrame->DoGetRasterCoverageInfos
+      (coverage, title, abstract, sample, pixel, compression, &srid) == false)
+    return;
+  dlg.Create(MainFrame, coverage, title, abstract, sample, pixel, compression);
+  dlg.ShowModal();
+}
+
+void MyTableTree::OnCmdDePyramidize(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - DePyramidize
+//
+  DePyramidizeDialog dlg;
+  wxString title;
+  wxString abstract;
+  wxString sample;
+  wxString pixel;
+  wxString compression;
+  int srid;
+  wxString coverage = CurrentRasterCoverageName;
+  int pos = CurrentRasterCoverageName.Find('[', true);
+  if (pos != wxNOT_FOUND)
+    coverage = CurrentRasterCoverageName.Left(pos - 1);
+  if (MainFrame->DoGetRasterCoverageInfos
+      (coverage, title, abstract, sample, pixel, compression, &srid) == false)
+    return;
+  dlg.Create(MainFrame, coverage, title, abstract, sample, pixel, compression);
+  dlg.ShowModal();
+}
+
+void MyTableTree::OnCmdRasterDrop(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - Drop Raster Coverage
+//
+  RasterDropDialog dlg;
+  wxString title;
+  wxString abstract;
+  wxString sample;
+  wxString pixel;
+  wxString compression;
+  int srid;
+  wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, Tree_RefreshDeferred);
+  wxString coverage = CurrentRasterCoverageName;
+  int pos = CurrentRasterCoverageName.Find('[', true);
+  if (pos != wxNOT_FOUND)
+    coverage = CurrentRasterCoverageName.Left(pos - 1);
+  if (MainFrame->DoGetRasterCoverageInfos
+      (coverage, title, abstract, sample, pixel, compression, &srid) == false)
+    return;
+  dlg.Create(MainFrame, coverage, title, abstract, sample, pixel, compression);
+  dlg.ShowModal();
+  // appending a delayed event so to really update the Tree
+  AddPendingEvent(evt);
+}
+
+void MyTableTree::OnRegisterVectorCoverage(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - Register Vector Coverage
+//
+  VectorRegisterDialog dlg;
+  wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, Tree_RefreshDeferred);
+  dlg.Create(MainFrame);
+  if (dlg.ShowModal() == wxID_OK)
+    {
+      wxString name = dlg.GetCoverageName();
+      wxString table = dlg.GetTableName();
+      wxString geometry = dlg.GetGeometryColumn();
+      wxString title = dlg.GetTitle();
+      wxString abstract = dlg.GetAbstract();
+      if (MainFrame->DoRegisterVectorCoverage(name, table, geometry, title,
+                                              abstract) != true)
         {
-          //
-          // fetching a row
-          //
-          sqlite3_reset(stmt2);
-          sqlite3_clear_bindings(stmt2);
-          n_cols = sqlite3_column_count(stmt1);
-          for (col_no = 1; col_no < n_cols; col_no++)
-            {
-              // saving column values
-              if (sqlite3_column_type(stmt1, col_no) == SQLITE_INTEGER)
-                value_list->SetValue(col_no - 1,
-                                     sqlite3_column_int64(stmt1, col_no));
-              if (sqlite3_column_type(stmt1, col_no) == SQLITE_FLOAT)
-                value_list->SetValue(col_no - 1,
-                                     sqlite3_column_double(stmt1, col_no));
-              if (sqlite3_column_type(stmt1, col_no) == SQLITE_TEXT)
-                {
-                  const char *xtext =
-                    (const char *) sqlite3_column_text(stmt1, col_no);
-                  value_list->SetValue(col_no - 1, xtext);
-                }
-              if (sqlite3_column_type(stmt1, col_no) == SQLITE_BLOB)
-                {
-                  const void *blob = sqlite3_column_blob(stmt1, col_no);
-                  int blob_size = sqlite3_column_bytes(stmt1, col_no);
-                  value_list->SetValue(col_no - 1, blob, blob_size);
-                }
-              if (sqlite3_column_type(stmt1, col_no) == SQLITE_NULL)
-                value_list->SetValue(col_no - 1);
-            }
-          if (doDeleteDuplicates2(stmt2, value_list, &xcnt) == true)
-            cnt += xcnt;
-          else
-            goto error;
+          wxMessageBox(wxT("Sorry, some error fatal occurred."),
+                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+          return;
       } else
         {
-          sprintf(xsql, "SQL error: %s",
-                  sqlite3_errmsg(MainFrame->GetSqlite()));
-          wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(xsql),
-                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
-          goto error;
+          wxMessageBox(wxT("Vector Coverage \"") + name +
+                       wxT("\" successfully registered"), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
         }
+      // appending a delayed event so to really update the Tree
+      AddPendingEvent(evt);
     }
+}
 
-  sqlite3_finalize(stmt1);
-  sqlite3_finalize(stmt2);
+void MyTableTree::OnCmdVectorUnregister(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - Unregister Vector Coverage
+//
+  VectorUnregisterDialog dlg;
+  wxString title;
+  wxString abstract;
+  wxString type;
+  int srid;
+  wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, Tree_RefreshDeferred);
+  wxString coverage = CurrentVectorCoverageName;
+  int pos = CurrentRasterCoverageName.Find('[', true);
+  if (pos != wxNOT_FOUND)
+    coverage = CurrentRasterCoverageName.Left(pos - 1);
+  if (MainFrame->DoGetVectorCoverageInfos
+      (coverage, title, abstract, type, &srid) == false)
+    return;
+  dlg.Create(MainFrame, coverage, title, abstract, type);
+  dlg.ShowModal();
+  // appending a delayed event so to really update the Tree
+  AddPendingEvent(evt);
+}
 
-// confirm the still pending Transaction 
-  ret = sqlite3_exec(MainFrame->GetSqlite(), "COMMIT", NULL, NULL, &sql_err);
-  if (ret != SQLITE_OK)
+void MyTableTree::OnCmdNewRasterStyle(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - new Raster Style creation required
+//
+  int ret;
+  wxString lastDir;
+  wxString path;
+  LoadRasterStyleDialog dlg;
+  wxString suffixList = wxT("XML Document (*.xml)|*.xml|");
+  suffixList += wxT("All files (*.*)|*.*");
+  wxFileDialog fileDialog(this, wxT("Add New SLD/SE Raster Style(s)"),
+                          wxT(""), wxT("style.xml"), suffixList,
+                          wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE,
+                          wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
     {
-      sprintf(xsql, "COMMIT TRANSACTION error: %s\n", sql_err);
-      wxMessageBox(wxString::FromUTF8(xsql),
-                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
-      sqlite3_free(sql_err);
-      return false;
+      int count;
+      wxArrayString paths;
+      fileDialog.GetPaths(paths);
+      count = paths.GetCount();
+      path = paths.Item(0);
+      int more = count - 1;
+      if (count >= 2)
+        {
+          path += wxT("\n") + paths.Item(1);
+          more--;
+        }
+      wxFileName file(path);
+      lastDir = file.GetPath();
+      MainFrame->SetLastDirectory(lastDir);
+      if (more > 0)
+        {
+          char dummy[128];
+          sprintf(dummy, "\n(and %d more %s)", more,
+                  (more > 1) ? "files" : "file");
+          path += wxString::FromUTF8(dummy);
+        }
+      dlg.Create(MainFrame, paths, path);
+      dlg.ShowModal();
     }
+}
 
-  ::wxEndBusyCursor();
-  *count = cnt;
-  return true;
-
-error:
-  *count = 0;
-  if (stmt1)
-    sqlite3_finalize(stmt1);
-  if (stmt2)
-    sqlite3_finalize(stmt2);
-
-// performing a ROLLBACK anyway 
-  ret = sqlite3_exec(MainFrame->GetSqlite(), "ROLLBACK", NULL, NULL, &sql_err);
-  if (ret != SQLITE_OK)
+void MyTableTree::OnCmdReloadRasterStyle(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - reloading a Raster Style was required
+//
+  int ret;
+  wxString lastDir;
+  wxString path;
+  ReloadRasterStyleDialog dlg;
+  wxString suffixList = wxT("XML Document (*.xml)|*.xml|");
+  suffixList += wxT("All files (*.*)|*.*");
+  wxFileDialog fileDialog(this,
+                          wxT
+                          ("Reloading an already existing SLD/SE Raster Style"),
+                          wxT(""), wxT("style.xml"), suffixList,
+                          wxFD_OPEN | wxFD_FILE_MUST_EXIST, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
     {
-      sprintf(xsql, "ROLLBACK TRANSACTION error: %s\n", sql_err);
-      wxMessageBox(wxString::FromUTF8(xsql),
-                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
-      sqlite3_free(sql_err);
-      return false;
+      path = fileDialog.GetPath();
+      wxFileName file(path);
+      lastDir = file.GetPath();
+      MainFrame->SetLastDirectory(lastDir);
+      dlg.Create(MainFrame, path);
+      dlg.ShowModal();
     }
+}
 
-  ::wxEndBusyCursor();
-  return false;
+void MyTableTree::OnCmdUnregisterRasterStyle(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - UnRegistering a Raster Style was required
+//
+  UnregisterRasterStyleDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
 }
 
-bool MyTableTree::doDeleteDuplicates2(sqlite3_stmt * stmt1,
-                                      DuplRow * value_list, int *count)
+void MyTableTree::OnCmdRasterSRIDs(wxCommandEvent & WXUNUSED(event))
 {
-// deleting duplicate rows [actual delete]
-  int cnt = 0;
-  int row_no = 0;
-  char xsql[8192];
-  char xname[1024];
-  int ret;
-  sqlite3_stmt *stmt2 = NULL;
-  DuplColumn *col;
-  wxString sql;
-  wxString where;
-  wxString condition;
-  bool first = true;
-  int qcnt = 0;
-  int param = 1;
-  bool match;
-  int n_cols;
-  int col_no;
+//
+// menu event - Handling Raster Coverage alternative SRIDs
+//
+  RasterSRIDsDialog dlg;
+  dlg.Create(MainFrame, CurrentRasterCoverageName);
+  dlg.ShowModal();
+}
 
-  *count = 0;
-  value_list->ResetQueryPos();
+void MyTableTree::OnCmdRasterKeywords(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - Handling Raster Coverage Keywords
+//
+  RasterKeywordsDialog dlg;
+  dlg.Create(MainFrame, CurrentRasterCoverageName);
+  dlg.ShowModal();
+}
 
-// preparing the query statement
-  sql = wxT("SELECT ROWID");
-  where = wxT("\nWHERE ");
-  col = value_list->GetFirst();
-  while (col)
+void MyTableTree::OnCmdRegisterExternalGraphic(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - new External Graphic creation required
+//
+  int ret;
+  wxString lastDir;
+  wxString path;
+  LoadExternalGraphicDialog dlg;
+  wxString suffixList =
+    wxT("Graphic resource (*.png;*.jpg;*.gif;*.svg)|*.png;*.jpg;*.gif;*.svg|");
+  suffixList += wxT("PNG image (*.png)|*.png|");
+  suffixList += wxT("JPEG image (*.jpg)|*.jpg|");
+  suffixList += wxT("GIF image (*.gif)|*.gif|");
+  suffixList += wxT("SVG symbol (*.svg)|*.svg|");
+  suffixList += wxT("All files (*.*)|*.*");
+  wxFileDialog fileDialog(this, wxT("Add New External Graphic resource(s)"),
+                          wxT(""), wxT(""), suffixList,
+                          wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE,
+                          wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
     {
-      if (col->GetType() == SQLITE_BLOB)
-        {
-          sql += wxT(", ");
-          sql += col->GetName();
-          col->SetQueryPos(qcnt++);
-      } else if (col->GetType() == SQLITE_NULL)
+      int count;
+      wxArrayString paths;
+      fileDialog.GetPaths(paths);
+      count = paths.GetCount();
+      path = paths.Item(0);
+      int more = count - 1;
+      if (count >= 2)
         {
-          if (first == true)
-            {
-              first = false;
-              condition = col->GetName();
-          } else
-            {
-              condition = wxT(" AND ");
-              condition += col->GetName();
-            }
-          condition += wxT(" IS NULL");
-          where += condition;
-      } else
+          path += wxT("\n") + paths.Item(1);
+          more--;
+        }
+      wxFileName file(path);
+      lastDir = file.GetPath();
+      MainFrame->SetLastDirectory(lastDir);
+      if (more > 0)
         {
-          if (first == true)
-            {
-              first = false;
-              condition = col->GetName();
-          } else
-            {
-              condition = wxT(" AND ");
-              condition += col->GetName();
-            }
-          condition += wxT(" = ?");
-          where += condition;
-          col->SetQueryPos(param++);
+          char dummy[128];
+          sprintf(dummy, "\n(and %d more %s)", more,
+                  (more > 1) ? "files" : "file");
+          path += wxString::FromUTF8(dummy);
         }
-      col = col->GetNext();
+      dlg.Create(MainFrame, paths, path);
+      dlg.ShowModal();
     }
-  sql += wxT("\nFROM ");
-  strcpy(xname, value_list->GetTable().ToUTF8());
-  MainFrame->DoubleQuotedSql(xname);
-  sql += wxString::FromUTF8(xname);
-  sql += where;
+}
 
-  strcpy(xsql, sql.ToUTF8());
-  ret =
-    sqlite3_prepare_v2(MainFrame->GetSqlite(), xsql, strlen(xsql), &stmt2,
-                       NULL);
-  if (ret != SQLITE_OK)
-    {
-      sprintf(xsql, "SQL error: %s", sqlite3_errmsg(MainFrame->GetSqlite()));
-      wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(xsql),
-                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
-      goto error;
-    }
+void MyTableTree::
+OnCmdUnregisterExternalGraphic(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - UnRegistering an External Graphic was required
+//
+  UnregisterExternalGraphicDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
+}
 
-  sqlite3_reset(stmt2);
-  sqlite3_clear_bindings(stmt2);
-  col = value_list->GetFirst();
-  while (col)
+void MyTableTree::OnCmdRegisterTextFont(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - new Text Font creation required
+//
+  int ret;
+  wxString lastDir;
+  wxString path;
+  LoadTextFontDialog dlg;
+  wxString suffixList = wxT("Text Font (*.ttf)|*.ttf|");
+  suffixList += wxT("All files (*.*)|*.*");
+  wxFileDialog fileDialog(this, wxT("Add New Text Font(s)"),
+                          wxT(""), wxT(""), suffixList,
+                          wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE,
+                          wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
     {
-      // binding query params
-      if (col->GetType() == SQLITE_INTEGER)
-        sqlite3_bind_int64(stmt2, col->GetQueryPos(), col->GetIntValue());
-      if (col->GetType() == SQLITE_FLOAT)
-        sqlite3_bind_double(stmt2, col->GetQueryPos(), col->GetDblValue());
-      if (col->GetType() == SQLITE_TEXT)
-        sqlite3_bind_text(stmt2, col->GetQueryPos(), col->GetTxtValue(),
-                          strlen(col->GetTxtValue()), SQLITE_STATIC);
-      col = col->GetNext();
+      int count;
+      wxArrayString paths;
+      fileDialog.GetPaths(paths);
+      count = paths.GetCount();
+      path = paths.Item(0);
+      int more = count - 1;
+      if (count >= 2)
+        {
+          path += wxT("\n") + paths.Item(1);
+          more--;
+        }
+      wxFileName file(path);
+      lastDir = file.GetPath();
+      MainFrame->SetLastDirectory(lastDir);
+      if (more > 0)
+        {
+          char dummy[128];
+          sprintf(dummy, "\n(and %d more %s)", more,
+                  (more > 1) ? "files" : "file");
+          path += wxString::FromUTF8(dummy);
+        }
+      dlg.Create(MainFrame, paths, path);
+      dlg.ShowModal();
     }
+}
 
-  while (1)
+void MyTableTree::OnCmdUnregisterTextFont(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - UnRegistering a Text Font was required
+//
+  MainFrame->DoCreateStylingTables();
+  UnregisterTextFontDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
+}
+
+void MyTableTree::OnCmdNewVectorStyle(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - new Vector Style creation required
+//
+  int ret;
+  wxString lastDir;
+  wxString path;
+  LoadVectorStyleDialog dlg;
+  wxString suffixList = wxT("XML Document (*.xml)|*.xml|");
+  suffixList += wxT("All files (*.*)|*.*");
+  wxFileDialog fileDialog(this, wxT("Add New SLD/SE Vector Style(s)"),
+                          wxT(""), wxT("style.xml"), suffixList,
+                          wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE,
+                          wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
     {
-      //
-      // fetching the result set rows 
-      //
-      ret = sqlite3_step(stmt2);
-      if (ret == SQLITE_DONE)
-        break;                  // end of result set
-      if (ret == SQLITE_ROW)
+      int count;
+      wxArrayString paths;
+      fileDialog.GetPaths(paths);
+      count = paths.GetCount();
+      path = paths.Item(0);
+      int more = count - 1;
+      if (count >= 2)
         {
-          //
-          // fetching a row
-          //
-          match = true;
-          n_cols = sqlite3_column_count(stmt2);
-          for (col_no = 1; col_no < n_cols; col_no++)
-            {
-              // checking blob columns
-              if (sqlite3_column_type(stmt2, col_no) == SQLITE_BLOB)
-                {
-                  const void *blob = sqlite3_column_blob(stmt2, col_no);
-                  int blob_size = sqlite3_column_bytes(stmt2, col_no);
-                  if (value_list->CheckBlob(col_no - 1, blob, blob_size) ==
-                      false)
-                    match = false;
-              } else
-                match = false;
-              if (match == false)
-                break;
-            }
-          if (match == false)
-            continue;
-          row_no++;
-          if (row_no > 1)
-            {
-              // deleting any duplicated row except the first one
-              sqlite3_reset(stmt1);
-              sqlite3_clear_bindings(stmt1);
-              sqlite3_bind_int64(stmt1, 1, sqlite3_column_int64(stmt2, 0));
-              ret = sqlite3_step(stmt1);
-              if (ret == SQLITE_DONE || ret == SQLITE_ROW)
-                cnt++;
-              else
-                {
-                  sprintf(xsql, "SQL error: %s",
-                          sqlite3_errmsg(MainFrame->GetSqlite()));
-                  wxMessageBox(wxT("SQLite SQL error: ") +
-                               wxString::FromUTF8(xsql), wxT("spatialite_gui"),
-                               wxOK | wxICON_ERROR, this);
-                  goto error;
-                }
-            }
-      } else
+          path += wxT("\n") + paths.Item(1);
+          more--;
+        }
+      wxFileName file(path);
+      lastDir = file.GetPath();
+      MainFrame->SetLastDirectory(lastDir);
+      if (more > 0)
         {
-          sprintf(xsql, "SQL error: %s",
-                  sqlite3_errmsg(MainFrame->GetSqlite()));
-          wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(xsql),
-                       wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
-          goto error;
+          char dummy[128];
+          sprintf(dummy, "\n(and %d more %s)", more,
+                  (more > 1) ? "files" : "file");
+          path += wxString::FromUTF8(dummy);
         }
+      dlg.Create(MainFrame, paths, path);
+      dlg.ShowModal();
     }
-  if (stmt2)
-    sqlite3_finalize(stmt2);
-  *count = cnt;
-  return true;
-
-error:
-  if (stmt2)
-    sqlite3_finalize(stmt2);
-  *count = 0;
-
-  return false;
 }
 
-DuplRow::~DuplRow()
+void MyTableTree::OnCmdReloadVectorStyle(wxCommandEvent & WXUNUSED(event))
 {
-// destructor
-  DuplColumn *p;
-  DuplColumn *pn;
-  p = First;
-  while (p)
+//
+// menu event - reloading a Vector Style was required
+//
+  int ret;
+  wxString lastDir;
+  wxString path;
+  ReloadVectorStyleDialog dlg;
+  wxString suffixList = wxT("XML Document (*.xml)|*.xml|");
+  suffixList += wxT("All files (*.*)|*.*");
+  wxFileDialog fileDialog(this,
+                          wxT
+                          ("Reloading an already existing SLD/SE Vector Style"),
+                          wxT(""), wxT("style.xml"), suffixList,
+                          wxFD_OPEN | wxFD_FILE_MUST_EXIST, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
     {
-      pn = p->GetNext();
-      delete p;
-      p = pn;
+      path = fileDialog.GetPath();
+      wxFileName file(path);
+      lastDir = file.GetPath();
+      MainFrame->SetLastDirectory(lastDir);
+      dlg.Create(MainFrame, path);
+      dlg.ShowModal();
     }
 }
 
-void DuplRow::Add(wxString & name)
+void MyTableTree::OnCmdUnregisterVectorStyle(wxCommandEvent & WXUNUSED(event))
 {
-// adding a column
-  DuplColumn *p = new DuplColumn(Count, name);
-  Count++;
-  if (First == NULL)
-    First = p;
-  if (Last)
-    Last->SetNext(p);
-  Last = p;
+//
+// menu event - UnRegistering a Vector Style was required
+//
+  UnregisterVectorStyleDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
 }
 
-void DuplRow::SetValue(int pos, sqlite3_int64 value)
+void MyTableTree::
+OnCmdRasterSymbolizerContrast(wxCommandEvent & WXUNUSED(event))
 {
-// setting up an integer value
-  DuplColumn *p = First;
-  while (p)
-    {
-      if (p->GetPos() == pos)
-        {
-          p->SetValue(value);
-          return;
-        }
-      p = p->GetNext();
-    }
+//
+// menu event - the RasterSymbolizer tool was invoked
+//
+  MainFrame->DoCreateStylingTables();
+  RasterSymbolizerContrastDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
 }
 
-void DuplRow::SetValue(int pos, double value)
+void MyTableTree::
+OnCmdRasterSymbolizerChannelRgb(wxCommandEvent & WXUNUSED(event))
 {
-// setting up a double value
-  DuplColumn *p = First;
-  while (p)
-    {
-      if (p->GetPos() == pos)
-        {
-          p->SetValue(value);
-          return;
-        }
-      p = p->GetNext();
-    }
+//
+// menu event - the RasterSymbolizer tool was invoked
+//
+  MainFrame->DoCreateStylingTables();
+  RasterSymbolizerChannelRgbDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
 }
 
-void DuplRow::SetValue(int pos, const char *value)
+void MyTableTree::
+OnCmdRasterSymbolizerChannelGray(wxCommandEvent & WXUNUSED(event))
 {
-// setting up a text value
-  DuplColumn *p = First;
-  while (p)
-    {
-      if (p->GetPos() == pos)
-        {
-          p->SetValue(value);
-          return;
-        }
-      p = p->GetNext();
-    }
+//
+// menu event - the RasterSymbolizer tool was invoked
+//
+  MainFrame->DoCreateStylingTables();
+  RasterSymbolizerChannelGrayDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
 }
 
-void DuplRow::SetValue(int pos, const void *blob, int size)
+void MyTableTree::
+OnCmdRasterSymbolizerCategorize(wxCommandEvent & WXUNUSED(event))
 {
-// setting up a blob value
-  DuplColumn *p = First;
-  while (p)
-    {
-      if (p->GetPos() == pos)
-        {
-          p->SetValue(blob, size);
-          return;
-        }
-      p = p->GetNext();
-    }
+//
+// menu event - the RasterSymbolizer tool was invoked
+//
+  MainFrame->DoCreateStylingTables();
+  RasterSymbolizerCategorizeDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
 }
 
-void DuplRow::SetValue(int pos)
+void MyTableTree::
+OnCmdRasterSymbolizerInterpolate(wxCommandEvent & WXUNUSED(event))
 {
-// setting up a NULL value
-  DuplColumn *p = First;
-  while (p)
-    {
-      if (p->GetPos() == pos)
-        {
-          p->SetValue();
-          return;
-        }
-      p = p->GetNext();
-    }
+//
+// menu event - the RasterSymbolizer tool was invoked
+//
+  MainFrame->DoCreateStylingTables();
+  RasterSymbolizerInterpolateDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
 }
 
-void DuplRow::ResetQueryPos()
+void MyTableTree::
+OnCmdRasterSymbolizerShadedRelief(wxCommandEvent & WXUNUSED(event))
 {
-// resetting QueryPos for BLOBs
-  DuplColumn *p = First;
-  while (p)
-    {
-      p->SetQueryPos(-1);
-      p = p->GetNext();
-    }
+//
+// menu event - the RasterSymbolizer tool was invoked
+//
+  MainFrame->DoCreateStylingTables();
+  RasterSymbolizerShadedReliefDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
+}
+
+void MyTableTree::
+OnCmdRasterSymbolizerMonochrome(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - the RasterSymbolizer tool was invoked
+//
+  MainFrame->DoCreateStylingTables();
+  RasterSymbolizerMonochromeDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
+}
+
+void MyTableTree::OnCmdSimpleLineSymbolizer(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - the LineSymbolizer tool was invoked
+//
+  MainFrame->DoCreateStylingTables();
+  SimpleLineSymbolizerDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
+}
+
+void MyTableTree::OnCmdSimplePolygonSymbolizer(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - the PolygonSymbolizer tool was invoked
+//
+  MainFrame->DoCreateStylingTables();
+  SimplePolygonSymbolizerDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
+}
+
+void MyTableTree::OnCmdSimplePointSymbolizer(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - the PointSymbolizer tool was invoked
+//
+  MainFrame->DoCreateStylingTables();
+  SimplePointSymbolizerDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
 }
 
-bool DuplRow::CheckBlob(int pos, const void *blob, int size)
+void MyTableTree::OnCmdSimpleTextSymbolizer(wxCommandEvent & WXUNUSED(event))
 {
-// checking a BLOB value 
-  DuplColumn *p = First;
-  while (p)
+//
+// menu event - the TextSymbolizer tool was invoked
+//
+  MainFrame->DoCreateStylingTables();
+  SimpleTextSymbolizerDialog dlg;
+  dlg.Create(MainFrame);
+  dlg.ShowModal();
+}
+
+bool MyTableTree::GetCurrentlySelectedTable(wxString & table_name)
+{
+// attempting to retrieve the currenlty selected Table Name
+  if (CurrentItem.IsOk() != true)
+    return false;
+  MyObject *obj = (MyObject *) GetItemData(CurrentItem);
+  if (obj == NULL)
+    return false;
+  if (obj->GetType() == MY_TABLE && obj->IsAttached() != true)
     {
-      if (p->GetQueryPos() == pos)
-        {
-          return p->CheckBlob(blob, size);
-        }
-      p = p->GetNext();
+      table_name = obj->GetName();
+      return true;
     }
   return false;
 }
 
-bool DuplColumn::CheckBlob(const void *blob, int size)
+void MyTableTree::OnCmdSldSeVectorStyles(wxCommandEvent & WXUNUSED(event))
 {
-// checking a BLOB value 
-  if (Type != SQLITE_BLOB)
-    return false;
-  if (Size != size)
-    return false;
-  if (memcmp(Blob, blob, size) != 0)
-    return false;
-  return true;
+//
+// menu event - Handling Vector Coverage SLD/SE styles
+//
+  VectorCoverageStylesDialog dlg;
+  dlg.Create(MainFrame, CurrentVectorCoverageName);
+  dlg.ShowModal();
+}
+
+void MyTableTree::OnCmdVectorSRIDs(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - Handling Vector Coverage alternative SRIDs
+//
+  VectorSRIDsDialog dlg;
+  dlg.Create(MainFrame, CurrentVectorCoverageName);
+  dlg.ShowModal();
+}
+
+void MyTableTree::OnCmdVectorKeywords(wxCommandEvent & WXUNUSED(event))
+{
+//
+// menu event - Handling Vector Coverage Keywords
+//
+  VectorKeywordsDialog dlg;
+  dlg.Create(MainFrame, CurrentVectorCoverageName);
+  dlg.ShowModal();
+}
+
+void MyTableTree::OnCreateRasterCoverage(wxCommandEvent & WXUNUSED(event))
+{
+//
+// creating a Raster Coverage
+//
+  int ret;
+  CreateRasterCoverageDialog dlg;
+  dlg.Create(MainFrame);
+  ret = dlg.ShowModal();
+  if (ret == wxID_OK)
+    {
+      wxString CoverageName = dlg.GetCoverageName();
+      wxString Title = dlg.GetTitle();
+      wxString Abstract = dlg.GetAbstract();
+      int SampleType = dlg.GetSampleType();
+      int PixelType = dlg.GetPixelType();
+      int NumBands = dlg.GetNumBands();
+      int Compression = dlg.GetCompression();
+      int Quality = dlg.GetQuality();
+      int TileWidth = dlg.GetTileWidth();
+      int TileHeight = dlg.GetTileHeight();
+      bool NotGeoreferenced = dlg.IsNotGeoreferenced();
+      int Srid = dlg.GetSrid();
+      double HorzResolution = dlg.GetHorzResolution();
+      double VertResolution = dlg.GetVertResolution();
+      wxString NoData = dlg.GetNoData();
+      bool StrictResolution = dlg.IsStrictResolution();
+      bool MixedResolutions = dlg.IsMixedResolutions();
+      bool InputPaths = dlg.IsInputPaths();
+      bool MD5 = dlg.IsMD5();
+      bool Summary = dlg.IsSummary();
+      int RedBand = dlg.GetRedBand();
+      int GreenBand = dlg.GetGreenBand();
+      int BlueBand = dlg.GetBlueBand();
+      int NIRband = dlg.GetNIRband();
+      bool AutoNDVI = dlg.IsAutoNDVI();
+      if (MainFrame->CreateRasterCoverage
+          (CoverageName, Title, Abstract, SampleType, PixelType, NumBands,
+           Compression, Quality, TileWidth, TileHeight, NotGeoreferenced, Srid,
+           HorzResolution, VertResolution, NoData, StrictResolution,
+           MixedResolutions, InputPaths, MD5, Summary, RedBand, GreenBand,
+           BlueBand, NIRband, AutoNDVI) == true)
+        {
+          wxMessageBox(wxT("Raster Coverage ") + CoverageName +
+                       wxT(" successfully created"), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+          wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, Tree_Refresh);
+          OnCmdRefresh(evt);
+        }
+    }
 }
diff --git a/TextCsv.cpp b/TextCsv.cpp
index 40df4e8..dea2d13 100644
--- a/TextCsv.cpp
+++ b/TextCsv.cpp
@@ -268,7 +268,7 @@ clean_up:
         free(*(col_name + i));
       free(col_name);
     }
-  free(text);
+  gaiaTextReaderDestroy(text);
   if (sqlError == true)
     {
       // some error occurred - ROLLBACK 
diff --git a/VectorSymbolizers1.cpp b/VectorSymbolizers1.cpp
new file mode 100644
index 0000000..86aabd1
--- /dev/null
+++ b/VectorSymbolizers1.cpp
@@ -0,0 +1,10242 @@
+/*
+/ VectorSymbolizers1.cpp
+/ various dialog classes
+/
+/ version 1.8, 2015 March 28
+/
+/ Author: Sandro Furieri a-furieri at lqt.it
+/
+/ Copyright (C) 2015  Alessandro Furieri
+/
+/    This program is free software: you can redistribute it and/or modify
+/    it under the terms of the GNU General Public License as published by
+/    the Free Software Foundation, either version 3 of the License, or
+/    (at your option) any later version.
+/
+/    This program is distributed in the hope that it will be useful,
+/    but WITHOUT ANY WARRANTY; without even the implied warranty of
+/    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/    GNU General Public License for more details.
+/
+/    You should have received a copy of the GNU General Public License
+/    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+/
+*/
+
+#include "Classdef.h"
+
+#include "wx/spinctrl.h"
+#include "wx/filename.h"
+#include "wx/colordlg.h"
+#include "wx/tokenzr.h"
+#include "wx/clipbrd.h"
+
+#include <rasterlite2/rasterlite2.h>
+#include <rasterlite2/rl2graphics.h>
+#include <rasterlite2/rl2svg.h>
+
+SimpleLineSymbolizerDialog::SimpleLineSymbolizerDialog()
+{
+// ctor
+  Stroke1DashArray = NULL;
+  Stroke2DashArray = NULL;
+  Stroke3DashArray = NULL;
+  List = NULL;
+}
+
+SimpleLineSymbolizerDialog::~SimpleLineSymbolizerDialog()
+{
+// dtor
+  if (Stroke1DashArray != NULL)
+    delete[]Stroke1DashArray;
+  if (Stroke2DashArray != NULL)
+    delete[]Stroke2DashArray;
+  if (Stroke3DashArray != NULL)
+    delete[]Stroke3DashArray;
+  if (List)
+    delete List;
+}
+
+bool SimpleLineSymbolizerDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Uom = GUI_UOM_PIXEL;
+  MinScale = false;
+  MaxScale = false;
+  PerpendicularOffset1 = 0.0;
+  Stroke1Opacity = 1.0;
+  HasGraphic1 = false;
+  Stroke1Color = wxT("#000000");
+  EnableStroke1Replacement = false;
+  Stroke1ColorReplacement = wxT("#000000");
+  Stroke1Width = 1.0;
+  Stroke1LineJoin = RL2_PEN_JOIN_ROUND;
+  Stroke1LineCap = RL2_PEN_CAP_ROUND;
+  Stroke1DashCount = 0;
+  Stroke1DashOffset = 0.0;
+  EnableStroke2 = false;
+  PerpendicularOffset2 = 0.0;
+  Stroke2Opacity = 1.0;
+  HasGraphic2 = false;
+  Stroke2Color = wxT("#000000");
+  EnableStroke2Replacement = false;
+  Stroke2ColorReplacement = wxT("#000000");
+  Stroke2Width = 1.0;
+  Stroke2LineJoin = RL2_PEN_JOIN_ROUND;
+  Stroke2LineCap = RL2_PEN_CAP_ROUND;
+  Stroke2DashCount = 0;
+  Stroke2DashOffset = 0.0;
+  EnableStroke3 = false;
+  PerpendicularOffset3 = 0.0;
+  Stroke3Opacity = 1.0;
+  HasGraphic3 = false;
+  Stroke3Color = wxT("#000000");
+  EnableStroke3Replacement = false;
+  Stroke3ColorReplacement = wxT("#000000");
+  Stroke3Width = 1.0;
+  Stroke3LineJoin = RL2_PEN_JOIN_ROUND;
+  Stroke3LineCap = RL2_PEN_CAP_ROUND;
+  Stroke3DashCount = 0;
+  Stroke3DashOffset = 0.0;
+  PreviewBackground = GUI_PREVIEW_BACKGROUND_CHECKED;
+  List = MainFrame->FindExternalGraphic(true);
+
+  if (wxPropertySheetDialog::Create
+      (parent, wxID_ANY, wxT("Simple Line Symbolizer")) == false)
+    return false;
+  wxBookCtrlBase *book = GetBookCtrl();
+// creates individual panels
+  wxPanel *mainPage = CreateMainPage(book);
+  book->AddPage(mainPage, wxT("General"), true);
+  wxPanel *stroke1Page = CreateStroke1Page(book);
+  book->AddPage(stroke1Page, wxT("Stroke #1"), false);
+  wxPanel *stroke2Page = CreateStroke2Page(book);
+  book->AddPage(stroke2Page, wxT("Stroke #2"), false);
+  wxPanel *stroke3Page = CreateStroke3Page(book);
+  book->AddPage(stroke3Page, wxT("Stroke #3"), false);
+  wxPanel *previewPage = CreatePreviewPage(book);
+  book->AddPage(previewPage, wxT("Preview"), false);
+
+  CreateButtons();
+  LayoutDialog();
+// appends event handler for TAB/PAGE changing
+  Connect(wxID_ANY, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING,
+          (wxObjectEventFunction) & SimpleLineSymbolizerDialog::OnPageChanging);
+  Connect(wxID_ANY, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
+          (wxObjectEventFunction) & SimpleLineSymbolizerDialog::OnPageChanged);
+// appends event handler for buttons
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimpleLineSymbolizerDialog::OnQuit);
+  Connect(ID_SYMBOLIZER_INSERT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimpleLineSymbolizerDialog::OnInsert);
+  Connect(ID_SYMBOLIZER_EXPORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimpleLineSymbolizerDialog::OnExport);
+  Connect(ID_SYMBOLIZER_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimpleLineSymbolizerDialog::OnCopy);
+// centers the dialog window
+  Centre();
+  UpdateMainPage();
+  return true;
+}
+
+wxPanel *SimpleLineSymbolizerDialog::CreateMainPage(wxWindow * parent)
+{
+//
+// creating the MAIN page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_MAIN);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+// first row: the LineSymbolizer Name
+  wxBoxSizer *nameSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(nameSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *nameLabel = new wxStaticText(panel, wxID_STATIC, wxT("&Name:"));
+  nameSizer->Add(nameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *nameCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_NAME, wxT(""),
+                                        wxDefaultPosition, wxSize(600, 22));
+  nameSizer->Add(nameCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the LineSymbolizer Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the LineSymbolizer Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_ABSTRACT, wxT(""),
+                   wxDefaultPosition, wxSize(600, 60),
+                   wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: UOM and Visibility Range
+  boxSizer->AddSpacer(50);
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// fourth row A: Unit Of Measure - UOM
+  wxString uom[3];
+  uom[0] = wxT("&Pixel");
+  uom[1] = wxT("&Metre");
+  uom[2] = wxT("&Inch");
+  wxRadioBox *uomBox = new wxRadioBox(panel, ID_SYMBOLIZER_UOM,
+                                      wxT("&Unit Of Measure"),
+                                      wxDefaultPosition,
+                                      wxDefaultSize, 3,
+                                      uom, 1,
+                                      wxRA_SPECIFY_ROWS);
+  miscSizer->Add(uomBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  uomBox->SetSelection(0);
+// fourth row B: optional Visibility Range
+  miscSizer->AddSpacer(50);
+  wxBoxSizer *visibilityBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(visibilityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *visibilityBox = new wxStaticBox(panel, wxID_STATIC,
+                                               wxT("Visibility Range"),
+                                               wxDefaultPosition,
+                                               wxDefaultSize);
+  wxBoxSizer *visibilitySizer =
+    new wxStaticBoxSizer(visibilityBox, wxHORIZONTAL);
+  visibilityBoxSizer->Add(visibilitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL,
+                          5);
+  wxString range[4];
+  range[0] = wxT("&None");
+  range[1] = wxT("&Min");
+  range[2] = wxT("&Max");
+  range[3] = wxT("&Both");
+  wxRadioBox *rangeBox = new wxRadioBox(panel, ID_SYMBOLIZER_MINMAX_SCALE,
+                                        wxT("&Range Type"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 4,
+                                        range, 2,
+                                        wxRA_SPECIFY_COLS);
+  visibilitySizer->Add(rangeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  rangeBox->SetSelection(0);
+  visibilitySizer->AddSpacer(20);
+  wxBoxSizer *scaleBoxSizer = new wxBoxSizer(wxVERTICAL);
+  visibilitySizer->Add(scaleBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *scaleMinSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMinSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *minScaleLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Min Scale:"));
+  scaleMinSizer->Add(minScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *minScaleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_MIN_SCALE, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  minScaleCtrl->Enable(false);
+  scaleMinSizer->Add(minScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *scaleMaxSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMaxSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *maxScaleLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Max Scale:"));
+  scaleMaxSizer->Add(maxScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *maxScaleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_MAX_SCALE, wxT("+Infinite"),
+                   wxDefaultPosition, wxSize(100, 22));
+  maxScaleCtrl->Enable(false);
+  scaleMaxSizer->Add(maxScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_UOM, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdUomChanged);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdScaleChanged);
+  return panel;
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdUomChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// UOM selection changed
+//
+  wxRadioBox *uomCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_UOM);
+  switch (uomCtrl->GetSelection())
+    {
+      case 1:
+        Uom = GUI_UOM_METRE;
+        break;
+      case 2:
+        Uom = GUI_UOM_INCH;
+        break;
+      default:
+        Uom = GUI_UOM_PIXEL;
+        break;
+    };
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdScaleChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Visibility Range selection changed
+//
+  wxRadioBox *scaleModeCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  switch (scaleModeCtrl->GetSelection())
+    {
+      case 0:
+        MinScale = false;
+        MaxScale = false;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 1:
+        MinScale = true;
+        MaxScale = false;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 2:
+        MinScale = false;
+        MaxScale = true;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+      case 3:
+        MinScale = true;
+        MaxScale = true;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+    };
+}
+
+wxPanel *SimpleLineSymbolizerDialog::CreateStroke1Page(wxWindow * parent)
+{
+//
+// creating the STROKE #1 page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_STROKE1);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+// first row A: the Stroke #1 Opacity and Perpendicular Offset
+  wxBoxSizer *opacityBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *opacityBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("Opacity"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *opacitySizer = new wxStaticBoxSizer(opacityBox, wxVERTICAL);
+  opacityBoxSizer->Add(opacitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxSlider *opacityCtrl =
+    new wxSlider(panel, ID_SYMBOLIZER_STROKE1_OPACITY, 100, 0, 100,
+                 wxDefaultPosition, wxSize(300, 45),
+                 wxSL_HORIZONTAL | wxSL_LABELS);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// first row B: PerpendicularOffset
+  wxBoxSizer *perpendicularBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  opacityBoxSizer->Add(perpendicularBoxSizer, 0,
+                       wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *perpendicularBox = new wxStaticBox(panel, wxID_STATIC,
+                                                  wxT("Perpendicular Offset"),
+                                                  wxDefaultPosition,
+                                                  wxDefaultSize);
+  wxBoxSizer *perpendicularSizer =
+    new wxStaticBoxSizer(perpendicularBox, wxVERTICAL);
+  perpendicularBoxSizer->Add(perpendicularSizer, 0,
+                             wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *perp1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  perpendicularSizer->Add(perp1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxTextCtrl *perpendicularCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_PERPENDICULAR, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  perp1Sizer->Add(perpendicularCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxStaticText *perp1Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT
+                                              ("Draw lines in parallel to the original geometry."));
+  perp1Sizer->Add(perp1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxStaticText *perp2Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT
+                                              ("Positive to the left-hand side. Negative numbers mean right."));
+  perpendicularSizer->Add(perp2Label, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// second row: Stroke color or Graphic
+  wxBoxSizer *strokeSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(strokeSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// second row A: Stroke Type
+  wxBoxSizer *stroke1Sizer = new wxBoxSizer(wxVERTICAL);
+  strokeSizer->Add(stroke1Sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxString type[2];
+  type[0] = wxT("&Color");
+  type[1] = wxT("&Graphic");
+  wxRadioBox *typeBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE1_TYPE,
+                                       wxT("&Stroke Type"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 2,
+                                       type, 1,
+                                       wxRA_SPECIFY_ROWS);
+  stroke1Sizer->Add(typeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  typeBox->SetSelection(0);
+// second row B: Stroke Color
+  wxBoxSizer *colorBoxSizer = new wxBoxSizer(wxVERTICAL);
+  stroke1Sizer->Add(colorBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *colorBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Stroke Color"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *colorSizer = new wxStaticBoxSizer(colorBox, wxVERTICAL);
+  colorBoxSizer->Add(colorSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *color1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(color1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *colorCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_COLOR, Stroke1Color,
+                   wxDefaultPosition, wxSize(80, 22));
+  color1Sizer->Add(colorCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxTextCtrl *sampleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_PICKER_HEX, wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  wxColour back = wxColour(0, 0, 0);
+  sampleCtrl->SetBackgroundColour(back);
+  color1Sizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxBoxSizer *pickerSizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(pickerSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *pick =
+    new wxButton(panel, ID_SYMBOLIZER_STROKE1_PICKER_BTN, wxT("&Pick a color"));
+  pickerSizer->Add(pick, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// second row C: GRID to select an External Graphic
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  strokeSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *gridBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("External Graphic resources"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxHORIZONTAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl1 =
+    new wxGrid(panel, ID_SYMBOLIZER_STROKE1_GRAPHIC, wxDefaultPosition,
+               wxSize(420, 150), wxALWAYS_SHOW_SB);
+  int count = 0;
+  ExternalGraphic *pE = List->GetFirst();
+  while (pE)
+    {
+      // counting how many lines are there
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl1->CreateGrid(count, 4, wxGrid::wxGridSelectRows);
+  GridCtrl1->SetColLabelValue(0, wxT("Graphic"));
+  GridCtrl1->SetColLabelValue(1, wxT("Title"));
+  GridCtrl1->SetColLabelValue(2, wxT("Abstract"));
+  GridCtrl1->SetColLabelValue(3, wxT("MimeType"));
+  count = 0;
+  pE = List->GetFirst();
+  while (pE)
+    {
+      // feeding grid rows
+      MyGraphicCellRenderer *renderer = new MyGraphicCellRenderer;
+      renderer->SetGraphic(pE->GetGraphic());
+      GridCtrl1->SetCellRenderer(count, 0, renderer);
+      GridCtrl1->SetCellValue(count, 1, pE->GetTitle());
+      GridCtrl1->SetCellValue(count, 2, pE->GetAbstract());
+      GridCtrl1->SetCellValue(count, 3, pE->GetMimeType());
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl1->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl1->AutoSize();
+  GridCtrl1->EnableEditing(false);
+  gridSizer->Add(GridCtrl1, 0, wxALIGN_RIGHT | wxALL, 5);
+  GridCtrl1->Enable(false);
+// second row C: Color Replacement
+  wxBoxSizer *replacementBoxSizer = new wxBoxSizer(wxVERTICAL);
+  GridSizer->Add(replacementBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *replacementBox = new wxStaticBox(panel, wxID_STATIC,
+                                                wxT("Color Replacement"),
+                                                wxDefaultPosition,
+                                                wxDefaultSize);
+  wxBoxSizer *replacementSizer =
+    new wxStaticBoxSizer(replacementBox, wxVERTICAL);
+  replacementBoxSizer->Add(replacementSizer, 0,
+                           wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxCheckBox *enableReplacementCtrl =
+    new wxCheckBox(panel, ID_SYMBOLIZER_STROKE1_ENABLE_REPLACEMENT,
+                   wxT("Enable"),
+                   wxDefaultPosition, wxDefaultSize);
+  enableReplacementCtrl->SetValue(false);
+  enableReplacementCtrl->Enable(false);
+  replacementSizer->Add(enableReplacementCtrl, 0,
+                        wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *replacement1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  replacementSizer->Add(replacement1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *replacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_REPLACEMENT,
+                   Stroke1ColorReplacement,
+                   wxDefaultPosition, wxSize(80, 22));
+  replacement1Sizer->Add(replacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  replacementCtrl->Enable(false);
+  wxTextCtrl *sampleReplacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_REPLACEMENT_HEX,
+                   wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  back = wxColour(0, 0, 0);
+  sampleReplacementCtrl->SetBackgroundColour(back);
+  replacement1Sizer->Add(sampleReplacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: Stroke-Width, Stroke-LineJoin, Stroke-LineCap and Stroke-Dasharray 
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// third row A: StrokeWidth
+  wxBoxSizer *widthBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(widthBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *widthBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Stroke Width"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *widthSizer = new wxStaticBoxSizer(widthBox, wxVERTICAL);
+  widthBoxSizer->Add(widthSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxTextCtrl *widthCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_WIDTH, wxT("1.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  widthSizer->Add(widthCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// third row B: LineJoin
+  wxString join[3];
+  join[0] = wxT("&Mitre");
+  join[1] = wxT("&Round");
+  join[2] = wxT("&Bevel");
+  wxRadioBox *joinBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE1_LINEJOIN,
+                                       wxT("&Line Join"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 3,
+                                       join, 1,
+                                       wxRA_SPECIFY_COLS);
+  miscSizer->Add(joinBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  joinBox->SetSelection(1);
+// third row C: LineCap
+  wxString cap[3];
+  cap[0] = wxT("&Butt");
+  cap[1] = wxT("&Round");
+  cap[2] = wxT("&Square");
+  wxRadioBox *capBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE1_LINECAP,
+                                      wxT("&Line Cap"),
+                                      wxDefaultPosition,
+                                      wxDefaultSize, 3,
+                                      cap, 1,
+                                      wxRA_SPECIFY_COLS);
+  miscSizer->Add(capBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  capBox->SetSelection(1);
+// third row D: DashArray and DashOffset
+  wxBoxSizer *dashBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(dashBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *dashBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("Dashed/Dotted Stroke"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *dashSizer = new wxStaticBoxSizer(dashBox, wxVERTICAL);
+  dashBoxSizer->Add(dashSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *dash1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  dashSizer->Add(dash1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *dash1Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT("Dash Array:"));
+  dash1Sizer->Add(dash1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *dashArrayCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_DASHARRAY, wxT(""),
+                   wxDefaultPosition, wxSize(200, 22));
+  dash1Sizer->Add(dashArrayCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxStaticText *dash2Label =
+    new wxStaticText(panel, wxID_STATIC, wxT("e.g. 10,3,2,3"));
+  dash2Label->SetForegroundColour(wxColour(255, 0, 0));
+  dash1Sizer->Add(dash2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *dash2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  dashSizer->Add(dash2Sizer, 0, wxALIGN_LEFT | wxALL, 0);
+  wxStaticText *dashOffsetLabel = new wxStaticText(panel, wxID_STATIC,
+                                                   wxT("Dash Offset:"));
+  dash2Sizer->Add(dashOffsetLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *dashOffsetCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_DASHOFFSET, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  dash2Sizer->Add(dashOffsetCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_STROKE1_TYPE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdStroke1TypeChanged);
+  Connect(ID_SYMBOLIZER_STROKE1_COLOR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdColor1Changed);
+  Connect(ID_SYMBOLIZER_STROKE1_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdColor1Picker);
+  Connect(ID_SYMBOLIZER_STROKE1_ENABLE_REPLACEMENT,
+          wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdStroke1EnableReplacementChanged);
+  Connect(ID_SYMBOLIZER_STROKE1_REPLACEMENT, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdReplacement1Changed);
+  Connect(ID_SYMBOLIZER_STROKE1_LINEJOIN, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdLineJoin1Changed);
+  Connect(ID_SYMBOLIZER_STROKE1_LINECAP, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdLineCap1Changed);
+  return panel;
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdStroke1TypeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// stroke type changed: updating the visual sample
+//
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE1_TYPE);
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_COLOR);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_STROKE1_PICKER_BTN);
+  if (typeBox->GetSelection() == 0)
+    HasGraphic1 = false;
+  else
+    HasGraphic1 = true;
+  RetrieveStroke1Page(false);
+  UpdateStroke1Page();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdColor1Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke color changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_PICKER_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdColor1Picker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_COLOR);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdStroke1EnableReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke #1 ColorReplacement enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE1_ENABLE_REPLACEMENT);
+  if (enableCtrl->IsChecked() == true)
+    EnableStroke1Replacement = true;
+  else
+    EnableStroke1Replacement = false;
+  RetrieveStroke1Page(false);
+  UpdateStroke1Page();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdReplacement1Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Color Replacement changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_REPLACEMENT);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_REPLACEMENT_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdLineJoin1Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// LineJoin selection changed
+//
+  wxRadioBox *lineJoinCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE1_LINEJOIN);
+  switch (lineJoinCtrl->GetSelection())
+    {
+      case 0:
+        Stroke1LineJoin = RL2_PEN_JOIN_MITER;
+        break;
+      case 2:
+        Stroke1LineJoin = RL2_PEN_JOIN_BEVEL;
+        break;
+      default:
+        Stroke1LineJoin = RL2_PEN_JOIN_ROUND;
+        break;
+    };
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdLineCap1Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// LineCap selection changed
+//
+  wxRadioBox *lineCapCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE1_LINECAP);
+  switch (lineCapCtrl->GetSelection())
+    {
+      case 0:
+        Stroke1LineCap = RL2_PEN_CAP_BUTT;
+        break;
+      case 2:
+        Stroke1LineCap = RL2_PEN_CAP_SQUARE;
+        break;
+      default:
+        Stroke1LineCap = RL2_PEN_CAP_ROUND;
+        break;
+    };
+}
+
+wxPanel *SimpleLineSymbolizerDialog::CreateStroke2Page(wxWindow * parent)
+{
+//
+// creating the STROKE #2 page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_STROKE2);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+// first row A: the Stroke #2 Opacity and Perpendicular Offset
+  wxBoxSizer *opacityBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *enableBox = new wxStaticBox(panel, wxID_STATIC,
+                                           wxT("Stroke #2"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize);
+  wxBoxSizer *enableSizer = new wxStaticBoxSizer(enableBox, wxVERTICAL);
+  opacityBoxSizer->Add(enableSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxCheckBox *enableCtrl = new wxCheckBox(panel, ID_SYMBOLIZER_STROKE2_ENABLE,
+                                          wxT("Enable"),
+                                          wxDefaultPosition, wxDefaultSize);
+  enableCtrl->SetValue(false);
+  enableSizer->Add(enableCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *opacityBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("Opacity"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *opacitySizer = new wxStaticBoxSizer(opacityBox, wxVERTICAL);
+  opacityBoxSizer->Add(opacitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxSlider *opacityCtrl =
+    new wxSlider(panel, ID_SYMBOLIZER_STROKE2_OPACITY, 100, 0, 100,
+                 wxDefaultPosition, wxSize(300, 45),
+                 wxSL_HORIZONTAL | wxSL_LABELS);
+  opacityCtrl->Enable(false);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// first row B: PerpendicularOffset
+  wxBoxSizer *perpendicularBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  opacityBoxSizer->Add(perpendicularBoxSizer, 0,
+                       wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *perpendicularBox = new wxStaticBox(panel, wxID_STATIC,
+                                                  wxT("Perpendicular Offset"),
+                                                  wxDefaultPosition,
+                                                  wxDefaultSize);
+  wxBoxSizer *perpendicularSizer =
+    new wxStaticBoxSizer(perpendicularBox, wxVERTICAL);
+  perpendicularBoxSizer->Add(perpendicularSizer, 0,
+                             wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *perp1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  perpendicularSizer->Add(perp1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxTextCtrl *perpendicularCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_PERPENDICULAR, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  perpendicularCtrl->Enable(false);
+  perp1Sizer->Add(perpendicularCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2);
+  wxStaticText *perp1Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT
+                                              ("Draw lines in parallel to the original geometry."));
+  perpendicularSizer->Add(perp1Label, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// second row: Stroke color or Graphic
+  wxBoxSizer *strokeSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(strokeSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// second row A: Stroke Type
+  wxBoxSizer *stroke1Sizer = new wxBoxSizer(wxVERTICAL);
+  strokeSizer->Add(stroke1Sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxString type[2];
+  type[0] = wxT("&Color");
+  type[1] = wxT("&Graphic");
+  wxRadioBox *typeBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE2_TYPE,
+                                       wxT("&Stroke Type"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 2,
+                                       type, 1,
+                                       wxRA_SPECIFY_ROWS);
+  stroke1Sizer->Add(typeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  typeBox->SetSelection(0);
+  typeBox->Enable(false);
+// second row B: Stroke Color
+  wxBoxSizer *colorBoxSizer = new wxBoxSizer(wxVERTICAL);
+  stroke1Sizer->Add(colorBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *colorBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Stroke Color"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *colorSizer = new wxStaticBoxSizer(colorBox, wxVERTICAL);
+  colorBoxSizer->Add(colorSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *color1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(color1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *colorCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_COLOR, Stroke2Color,
+                   wxDefaultPosition, wxSize(80, 22));
+  colorCtrl->Enable(false);
+  color1Sizer->Add(colorCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxTextCtrl *sampleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_PICKER_HEX, wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  wxColour back = wxColour(0, 0, 0);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Enable(false);
+  color1Sizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxBoxSizer *pickerSizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(pickerSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *pick =
+    new wxButton(panel, ID_SYMBOLIZER_STROKE2_PICKER_BTN, wxT("&Pick a color"));
+  pick->Enable(false);
+  pickerSizer->Add(pick, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// second row C: GRID to select an External Graphic
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  strokeSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *gridBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("External Graphic resources"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxHORIZONTAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl2 =
+    new wxGrid(panel, ID_SYMBOLIZER_STROKE2_GRAPHIC, wxDefaultPosition,
+               wxSize(420, 150), wxALWAYS_SHOW_SB);
+  int count = 0;
+  ExternalGraphic *pE = List->GetFirst();
+  while (pE)
+    {
+      // counting how many lines are there
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl2->CreateGrid(count, 4, wxGrid::wxGridSelectRows);
+  GridCtrl2->SetColLabelValue(0, wxT("Graphic"));
+  GridCtrl2->SetColLabelValue(1, wxT("Title"));
+  GridCtrl2->SetColLabelValue(2, wxT("Abstract"));
+  GridCtrl2->SetColLabelValue(3, wxT("MimeType"));
+  count = 0;
+  pE = List->GetFirst();
+  while (pE)
+    {
+      // feeding grid rows
+      MyGraphicCellRenderer *renderer = new MyGraphicCellRenderer;
+      renderer->SetGraphic(pE->GetGraphic());
+      GridCtrl2->SetCellRenderer(count, 0, renderer);
+      GridCtrl2->SetCellValue(count, 1, pE->GetTitle());
+      GridCtrl2->SetCellValue(count, 2, pE->GetAbstract());
+      GridCtrl2->SetCellValue(count, 3, pE->GetMimeType());
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl2->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl2->AutoSize();
+  GridCtrl2->EnableEditing(false);
+  gridSizer->Add(GridCtrl2, 0, wxALIGN_RIGHT | wxALL, 5);
+  GridCtrl2->Enable(false);
+// second row C: Color Replacement
+  wxBoxSizer *replacementBoxSizer = new wxBoxSizer(wxVERTICAL);
+  GridSizer->Add(replacementBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *replacementBox = new wxStaticBox(panel, wxID_STATIC,
+                                                wxT("Color Replacement"),
+                                                wxDefaultPosition,
+                                                wxDefaultSize);
+  wxBoxSizer *replacementSizer =
+    new wxStaticBoxSizer(replacementBox, wxVERTICAL);
+  replacementBoxSizer->Add(replacementSizer, 0,
+                           wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxCheckBox *enableReplacementCtrl =
+    new wxCheckBox(panel, ID_SYMBOLIZER_STROKE2_ENABLE_REPLACEMENT,
+                   wxT("Enable"),
+                   wxDefaultPosition, wxDefaultSize);
+  enableReplacementCtrl->SetValue(false);
+  enableReplacementCtrl->Enable(false);
+  replacementSizer->Add(enableReplacementCtrl, 0,
+                        wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *replacement1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  replacementSizer->Add(replacement1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *replacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_REPLACEMENT,
+                   Stroke2ColorReplacement,
+                   wxDefaultPosition, wxSize(80, 22));
+  replacement1Sizer->Add(replacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  replacementCtrl->Enable(false);
+  wxTextCtrl *sampleReplacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_REPLACEMENT_HEX,
+                   wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  back = wxColour(0, 0, 0);
+  sampleReplacementCtrl->SetBackgroundColour(back);
+  replacement1Sizer->Add(sampleReplacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: Stroke-Width, Stroke-LineJoin, Stroke-LineCap and Stroke-Dasharray 
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// third row A: StrokeWidth
+  wxBoxSizer *widthBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(widthBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *widthBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Stroke Width"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *widthSizer = new wxStaticBoxSizer(widthBox, wxVERTICAL);
+  widthBoxSizer->Add(widthSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxTextCtrl *widthCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_WIDTH, wxT("1.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  widthCtrl->Enable(false);
+  widthSizer->Add(widthCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// third row B: LineJoin
+  wxString join[3];
+  join[0] = wxT("&Mitre");
+  join[1] = wxT("&Round");
+  join[2] = wxT("&Bevel");
+  wxRadioBox *joinBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE2_LINEJOIN,
+                                       wxT("&Line Join"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 3,
+                                       join, 1,
+                                       wxRA_SPECIFY_COLS);
+  miscSizer->Add(joinBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  joinBox->SetSelection(1);
+  joinBox->Enable(false);
+// third row C: LineCap
+  wxString cap[3];
+  cap[0] = wxT("&Butt");
+  cap[1] = wxT("&Round");
+  cap[2] = wxT("&Square");
+  wxRadioBox *capBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE2_LINECAP,
+                                      wxT("&Line Cap"),
+                                      wxDefaultPosition,
+                                      wxDefaultSize, 3,
+                                      cap, 1,
+                                      wxRA_SPECIFY_COLS);
+  miscSizer->Add(capBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  capBox->SetSelection(1);
+  capBox->Enable(false);
+// third row D: DashArray and DashOffset
+  wxBoxSizer *dashBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(dashBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *dashBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("Dashed/Dotted Stroke"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *dashSizer = new wxStaticBoxSizer(dashBox, wxVERTICAL);
+  dashBoxSizer->Add(dashSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *dash1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  dashSizer->Add(dash1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *dash1Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT("Dash Array:"));
+  dash1Sizer->Add(dash1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *dashArrayCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_DASHARRAY, wxT(""),
+                   wxDefaultPosition, wxSize(200, 22));
+  dashArrayCtrl->Enable(false);
+  dash1Sizer->Add(dashArrayCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxStaticText *dash2Label =
+    new wxStaticText(panel, wxID_STATIC, wxT("e.g. 10,3,2,3"));
+  dash2Label->SetForegroundColour(wxColour(255, 0, 0));
+  dash1Sizer->Add(dash2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *dash2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  dashSizer->Add(dash2Sizer, 0, wxALIGN_LEFT | wxALL, 0);
+  wxStaticText *dashOffsetLabel = new wxStaticText(panel, wxID_STATIC,
+                                                   wxT("Dash Offset:"));
+  dash2Sizer->Add(dashOffsetLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *dashOffsetCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_DASHOFFSET, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  dashOffsetCtrl->Enable(false);
+  dash2Sizer->Add(dashOffsetCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_STROKE2_ENABLE, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdStroke2Changed);
+  Connect(ID_SYMBOLIZER_STROKE2_TYPE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdStroke2TypeChanged);
+  Connect(ID_SYMBOLIZER_STROKE2_COLOR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdColor2Changed);
+  Connect(ID_SYMBOLIZER_STROKE2_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdColor2Picker);
+  Connect(ID_SYMBOLIZER_STROKE2_ENABLE_REPLACEMENT,
+          wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdStroke2EnableReplacementChanged);
+  Connect(ID_SYMBOLIZER_STROKE2_REPLACEMENT, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdReplacement2Changed);
+  Connect(ID_SYMBOLIZER_STROKE2_LINEJOIN, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdLineJoin2Changed);
+  Connect(ID_SYMBOLIZER_STROKE2_LINECAP, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdLineCap2Changed);
+  return panel;
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdStroke2Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke #2 enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE2_ENABLE);
+  if (enableCtrl->IsChecked() == true)
+    EnableStroke2 = true;
+  else
+    EnableStroke2 = false;
+  RetrieveStroke2Page(false);
+  UpdateStroke2Page();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdStroke2TypeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// stroke type changed: updating the visual sample
+//
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE2_TYPE);
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_COLOR);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_STROKE2_PICKER_BTN);
+  if (typeBox->GetSelection() == 0)
+    HasGraphic2 = false;
+  else
+    HasGraphic2 = true;
+  RetrieveStroke2Page(false);
+  UpdateStroke2Page();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdColor2Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke color changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_PICKER_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdColor2Picker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_COLOR);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdStroke2EnableReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke #2 ColorReplacement enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE2_ENABLE_REPLACEMENT);
+  if (enableCtrl->IsChecked() == true)
+    EnableStroke2Replacement = true;
+  else
+    EnableStroke2Replacement = false;
+  RetrieveStroke2Page(false);
+  UpdateStroke2Page();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdReplacement2Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Color Replacement changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_REPLACEMENT);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_REPLACEMENT_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdLineJoin2Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// LineJoin selection changed
+//
+  wxRadioBox *lineJoinCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE2_LINEJOIN);
+  switch (lineJoinCtrl->GetSelection())
+    {
+      case 0:
+        Stroke2LineJoin = RL2_PEN_JOIN_MITER;
+        break;
+      case 2:
+        Stroke2LineJoin = RL2_PEN_JOIN_BEVEL;
+        break;
+      default:
+        Stroke2LineJoin = RL2_PEN_JOIN_ROUND;
+        break;
+    };
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdLineCap2Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// LineCap selection changed
+//
+  wxRadioBox *lineCapCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE2_LINECAP);
+  switch (lineCapCtrl->GetSelection())
+    {
+      case 0:
+        Stroke2LineCap = RL2_PEN_CAP_BUTT;
+        break;
+      case 2:
+        Stroke2LineCap = RL2_PEN_CAP_SQUARE;
+        break;
+      default:
+        Stroke2LineCap = RL2_PEN_CAP_ROUND;
+        break;
+    };
+}
+
+wxPanel *SimpleLineSymbolizerDialog::CreateStroke3Page(wxWindow * parent)
+{
+//
+// creating the STROKE #3 page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_STROKE3);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+// first row A: the Stroke #3 Opacity and Perpendicular Offset
+  wxBoxSizer *opacityBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *enableBox = new wxStaticBox(panel, wxID_STATIC,
+                                           wxT("Stroke #3"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize);
+  wxBoxSizer *enableSizer = new wxStaticBoxSizer(enableBox, wxVERTICAL);
+  opacityBoxSizer->Add(enableSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxCheckBox *enableCtrl = new wxCheckBox(panel, ID_SYMBOLIZER_STROKE3_ENABLE,
+                                          wxT("Enable"),
+                                          wxDefaultPosition, wxDefaultSize);
+  enableCtrl->SetValue(false);
+  enableSizer->Add(enableCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *opacityBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("Opacity"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *opacitySizer = new wxStaticBoxSizer(opacityBox, wxVERTICAL);
+  opacityBoxSizer->Add(opacitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxSlider *opacityCtrl =
+    new wxSlider(panel, ID_SYMBOLIZER_STROKE3_OPACITY, 100, 0, 100,
+                 wxDefaultPosition, wxSize(300, 45),
+                 wxSL_HORIZONTAL | wxSL_LABELS);
+  opacityCtrl->Enable(false);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// first row B: PerpendicularOffset
+  wxBoxSizer *perpendicularBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  opacityBoxSizer->Add(perpendicularBoxSizer, 0,
+                       wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *perpendicularBox = new wxStaticBox(panel, wxID_STATIC,
+                                                  wxT("Perpendicular Offset"),
+                                                  wxDefaultPosition,
+                                                  wxDefaultSize);
+  wxBoxSizer *perpendicularSizer =
+    new wxStaticBoxSizer(perpendicularBox, wxVERTICAL);
+  perpendicularBoxSizer->Add(perpendicularSizer, 0,
+                             wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *perp1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  perpendicularSizer->Add(perp1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxTextCtrl *perpendicularCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE3_PERPENDICULAR, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  perpendicularCtrl->Enable(false);
+  perp1Sizer->Add(perpendicularCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2);
+  wxStaticText *perp1Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT
+                                              ("Draw lines in parallel to the original geometry."));
+  perpendicularSizer->Add(perp1Label, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// second row: Stroke color or Graphic
+  wxBoxSizer *strokeSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(strokeSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// second row A: Stroke Type
+  wxBoxSizer *stroke1Sizer = new wxBoxSizer(wxVERTICAL);
+  strokeSizer->Add(stroke1Sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxString type[2];
+  type[0] = wxT("&Color");
+  type[1] = wxT("&Graphic");
+  wxRadioBox *typeBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE3_TYPE,
+                                       wxT("&Stroke Type"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 2,
+                                       type, 1,
+                                       wxRA_SPECIFY_ROWS);
+  stroke1Sizer->Add(typeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  typeBox->SetSelection(0);
+  typeBox->Enable(false);
+// second row B: Stroke Color
+  wxBoxSizer *colorBoxSizer = new wxBoxSizer(wxVERTICAL);
+  stroke1Sizer->Add(colorBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *colorBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Stroke Color"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *colorSizer = new wxStaticBoxSizer(colorBox, wxVERTICAL);
+  colorBoxSizer->Add(colorSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *color1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(color1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *colorCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE3_COLOR, Stroke3Color,
+                   wxDefaultPosition, wxSize(80, 22));
+  colorCtrl->Enable(false);
+  color1Sizer->Add(colorCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxTextCtrl *sampleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE3_PICKER_HEX, wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  wxColour back = wxColour(0, 0, 0);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Enable(false);
+  color1Sizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxBoxSizer *pickerSizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(pickerSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *pick =
+    new wxButton(panel, ID_SYMBOLIZER_STROKE3_PICKER_BTN, wxT("&Pick a color"));
+  pick->Enable(false);
+  pickerSizer->Add(pick, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// second row C: GRID to select an External Graphic
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  strokeSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *gridBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("External Graphic resources"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxHORIZONTAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl3 =
+    new wxGrid(panel, ID_SYMBOLIZER_STROKE3_GRAPHIC, wxDefaultPosition,
+               wxSize(420, 150), wxALWAYS_SHOW_SB);
+  int count = 0;
+  ExternalGraphic *pE = List->GetFirst();
+  while (pE)
+    {
+      // counting how many lines are there
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl3->CreateGrid(count, 4, wxGrid::wxGridSelectRows);
+  GridCtrl3->SetColLabelValue(0, wxT("Graphic"));
+  GridCtrl3->SetColLabelValue(1, wxT("Title"));
+  GridCtrl3->SetColLabelValue(2, wxT("Abstract"));
+  GridCtrl3->SetColLabelValue(3, wxT("MimeType"));
+  count = 0;
+  pE = List->GetFirst();
+  while (pE)
+    {
+      // feeding grid rows
+      MyGraphicCellRenderer *renderer = new MyGraphicCellRenderer;
+      renderer->SetGraphic(pE->GetGraphic());
+      GridCtrl3->SetCellRenderer(count, 0, renderer);
+      GridCtrl3->SetCellValue(count, 1, pE->GetTitle());
+      GridCtrl3->SetCellValue(count, 2, pE->GetAbstract());
+      GridCtrl3->SetCellValue(count, 3, pE->GetMimeType());
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl3->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl3->AutoSize();
+  GridCtrl3->EnableEditing(false);
+  gridSizer->Add(GridCtrl3, 0, wxALIGN_RIGHT | wxALL, 5);
+  GridCtrl3->Enable(false);
+// second row C: Color Replacement
+  wxBoxSizer *replacementBoxSizer = new wxBoxSizer(wxVERTICAL);
+  GridSizer->Add(replacementBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *replacementBox = new wxStaticBox(panel, wxID_STATIC,
+                                                wxT("Color Replacement"),
+                                                wxDefaultPosition,
+                                                wxDefaultSize);
+  wxBoxSizer *replacementSizer =
+    new wxStaticBoxSizer(replacementBox, wxVERTICAL);
+  replacementBoxSizer->Add(replacementSizer, 0,
+                           wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxCheckBox *enableReplacementCtrl =
+    new wxCheckBox(panel, ID_SYMBOLIZER_STROKE3_ENABLE_REPLACEMENT,
+                   wxT("Enable"),
+                   wxDefaultPosition, wxDefaultSize);
+  enableReplacementCtrl->SetValue(false);
+  enableReplacementCtrl->Enable(false);
+  replacementSizer->Add(enableReplacementCtrl, 0,
+                        wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *replacement1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  replacementSizer->Add(replacement1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *replacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE3_REPLACEMENT,
+                   Stroke3ColorReplacement,
+                   wxDefaultPosition, wxSize(80, 22));
+  replacement1Sizer->Add(replacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  replacementCtrl->Enable(false);
+  wxTextCtrl *sampleReplacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE3_REPLACEMENT_HEX,
+                   wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  back = wxColour(0, 0, 0);
+  sampleReplacementCtrl->SetBackgroundColour(back);
+  replacement1Sizer->Add(sampleReplacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: Stroke-Width, Stroke-LineJoin, Stroke-LineCap and Stroke-Dasharray 
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// third row A: StrokeWidth
+  wxBoxSizer *widthBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(widthBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *widthBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Stroke Width"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *widthSizer = new wxStaticBoxSizer(widthBox, wxVERTICAL);
+  widthBoxSizer->Add(widthSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxTextCtrl *widthCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE3_WIDTH, wxT("1.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  widthCtrl->Enable(false);
+  widthSizer->Add(widthCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// third row B: LineJoin
+  wxString join[3];
+  join[0] = wxT("&Mitre");
+  join[1] = wxT("&Round");
+  join[2] = wxT("&Bevel");
+  wxRadioBox *joinBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE3_LINEJOIN,
+                                       wxT("&Line Join"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 3,
+                                       join, 1,
+                                       wxRA_SPECIFY_COLS);
+  miscSizer->Add(joinBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  joinBox->SetSelection(1);
+  joinBox->Enable(false);
+// third row C: LineCap
+  wxString cap[3];
+  cap[0] = wxT("&Butt");
+  cap[1] = wxT("&Round");
+  cap[2] = wxT("&Square");
+  wxRadioBox *capBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE3_LINECAP,
+                                      wxT("&Line Cap"),
+                                      wxDefaultPosition,
+                                      wxDefaultSize, 3,
+                                      cap, 1,
+                                      wxRA_SPECIFY_COLS);
+  miscSizer->Add(capBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  capBox->SetSelection(1);
+  capBox->Enable(false);
+// third row D: DashArray and DashOffset
+  wxBoxSizer *dashBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(dashBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *dashBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("Dashed/Dotted Stroke"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *dashSizer = new wxStaticBoxSizer(dashBox, wxVERTICAL);
+  dashBoxSizer->Add(dashSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *dash1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  dashSizer->Add(dash1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *dash1Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT("Dash Array:"));
+  dash1Sizer->Add(dash1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *dashArrayCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE3_DASHARRAY, wxT(""),
+                   wxDefaultPosition, wxSize(200, 22));
+  dashArrayCtrl->Enable(false);
+  dash1Sizer->Add(dashArrayCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxStaticText *dash2Label =
+    new wxStaticText(panel, wxID_STATIC, wxT("e.g. 10,3,2,3"));
+  dash2Label->SetForegroundColour(wxColour(255, 0, 0));
+  dash1Sizer->Add(dash2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *dash2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  dashSizer->Add(dash2Sizer, 0, wxALIGN_LEFT | wxALL, 0);
+  wxStaticText *dashOffsetLabel = new wxStaticText(panel, wxID_STATIC,
+                                                   wxT("Dash Offset:"));
+  dash2Sizer->Add(dashOffsetLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *dashOffsetCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE3_DASHOFFSET, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  dashOffsetCtrl->Enable(false);
+  dash2Sizer->Add(dashOffsetCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_STROKE3_ENABLE, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdStroke3Changed);
+  Connect(ID_SYMBOLIZER_STROKE3_TYPE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdStroke3TypeChanged);
+  Connect(ID_SYMBOLIZER_STROKE3_COLOR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdColor3Changed);
+  Connect(ID_SYMBOLIZER_STROKE3_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdColor3Picker);
+  Connect(ID_SYMBOLIZER_STROKE3_ENABLE_REPLACEMENT,
+          wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdStroke3EnableReplacementChanged);
+  Connect(ID_SYMBOLIZER_STROKE3_REPLACEMENT, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdReplacement3Changed);
+  Connect(ID_SYMBOLIZER_STROKE3_LINEJOIN, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdLineJoin3Changed);
+  Connect(ID_SYMBOLIZER_STROKE3_LINECAP, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdLineCap3Changed);
+  return panel;
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdStroke3Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke #3 enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE3_ENABLE);
+  if (enableCtrl->IsChecked() == true)
+    EnableStroke3 = true;
+  else
+    EnableStroke3 = false;
+  RetrieveStroke3Page(false);
+  UpdateStroke3Page();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdStroke3TypeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// stroke type changed: updating the visual sample
+//
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE3_TYPE);
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_COLOR);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_STROKE3_PICKER_BTN);
+  if (typeBox->GetSelection() == 0)
+    HasGraphic3 = false;
+  else
+    HasGraphic3 = true;
+  RetrieveStroke3Page(false);
+  UpdateStroke3Page();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdColor3Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke color changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_PICKER_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdColor3Picker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_COLOR);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdStroke3EnableReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke #3 ColorReplacement enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE3_ENABLE_REPLACEMENT);
+  if (enableCtrl->IsChecked() == true)
+    EnableStroke3Replacement = true;
+  else
+    EnableStroke3Replacement = false;
+  RetrieveStroke3Page(false);
+  UpdateStroke3Page();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdReplacement3Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Color Replacement changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_REPLACEMENT);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_REPLACEMENT_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdLineJoin3Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// LineJoin selection changed
+//
+  wxRadioBox *lineJoinCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE3_LINEJOIN);
+  switch (lineJoinCtrl->GetSelection())
+    {
+      case 0:
+        Stroke3LineJoin = RL2_PEN_JOIN_MITER;
+        break;
+      case 2:
+        Stroke3LineJoin = RL2_PEN_JOIN_BEVEL;
+        break;
+      default:
+        Stroke3LineJoin = RL2_PEN_JOIN_ROUND;
+        break;
+    };
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdLineCap3Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// LineCap selection changed
+//
+  wxRadioBox *lineCapCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE3_LINECAP);
+  switch (lineCapCtrl->GetSelection())
+    {
+      case 0:
+        Stroke3LineCap = RL2_PEN_CAP_BUTT;
+        break;
+      case 2:
+        Stroke3LineCap = RL2_PEN_CAP_SQUARE;
+        break;
+      default:
+        Stroke3LineCap = RL2_PEN_CAP_ROUND;
+        break;
+    };
+}
+
+wxPanel *SimpleLineSymbolizerDialog::CreatePreviewPage(wxWindow * parent)
+{
+//
+// creating the Preview page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_PREVIEW);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxHORIZONTAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+  wxBoxSizer *previewBoxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(previewBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// creating a control to show the LineSymbolizer Preview
+  wxStaticBox *previewBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("LineSymbolizer Preview"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *previewSizer = new wxStaticBoxSizer(previewBox, wxVERTICAL);
+  previewBoxSizer->Add(previewSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  DrawPreview(500, 300);
+  SymbolizerPreview *previewCtrl =
+    new SymbolizerPreview(this, panel, ID_SYMBOLIZER_PREVIEW,
+                          PreviewBackBitmap, wxSize(500, 300));
+  previewSizer->Add(previewCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// Background selector
+  wxString back[3];
+  back[0] = wxT("&Checked");
+  back[1] = wxT("&White");
+  back[2] = wxT("&Black");
+  wxRadioBox *backBox = new wxRadioBox(panel, ID_SYMBOLIZER_BACKGROUND,
+                                       wxT("&Background"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 3,
+                                       back, 1,
+                                       wxRA_SPECIFY_COLS);
+  boxSizer->Add(backBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  backBox->SetSelection(0);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_BACKGROUND, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleLineSymbolizerDialog::OnCmdBackgroundChanged);
+  return panel;
+}
+
+void SimpleLineSymbolizerDialog::
+OnCmdBackgroundChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Preview Background selection changed
+//
+  wxRadioBox *backCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_BACKGROUND);
+  switch (backCtrl->GetSelection())
+    {
+      case 1:
+        PreviewBackground = GUI_PREVIEW_BACKGROUND_WHITE;
+        break;
+      case 2:
+        PreviewBackground = GUI_PREVIEW_BACKGROUND_BLACK;
+        break;
+      default:
+        PreviewBackground = GUI_PREVIEW_BACKGROUND_CHECKED;
+        break;
+    };
+  UpdatePreviewPage();
+}
+
+void SimpleLineSymbolizerDialog::DrawPreview(int horz, int vert)
+{
+//
+// drawing a Symbolizer Preview
+//
+  PreviewBackBitmap.Create(horz, vert);
+  wxMemoryDC dc(PreviewBackBitmap);
+//
+// background filling
+//
+  wxImage img(24, 24);
+  for (int y = 0; y < 24; y++)
+    {
+      // creating a checked background
+      for (int x = 0; x < 24; x++)
+        {
+          if (y < 12)
+            {
+              if (x < 12)
+                img.SetRGB(x, y, 176, 176, 176);
+              else
+                img.SetRGB(x, y, 208, 208, 208);
+          } else
+            {
+              if (x < 12)
+                img.SetRGB(x, y, 208, 208, 208);
+              else
+                img.SetRGB(x, y, 176, 176, 176);
+            }
+        }
+    }
+  wxBrush stipple(img);
+  dc.SetBrush(stipple);
+  dc.DrawRectangle(0, 0, horz, vert);
+}
+
+void SimpleLineSymbolizerDialog::CreateButtons()
+{
+// 
+// adding the common Buttons
+//
+  wxBoxSizer *topSizer = (wxBoxSizer *) (this->GetSizer());
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  topSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *insert =
+    new wxButton(this, ID_SYMBOLIZER_INSERT, wxT("&Insert into DBMS"));
+  btnBox->Add(insert, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *exp =
+    new wxButton(this, ID_SYMBOLIZER_EXPORT, wxT("&Export to file"));
+  btnBox->Add(exp, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *copy = new wxButton(this, ID_SYMBOLIZER_COPY, wxT("&Copy"));
+  btnBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+}
+
+bool SimpleLineSymbolizerDialog::FinalValidityCheck()
+{
+//
+// last check before generating the SLD/SE Style
+//
+  if (Name.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the LineSymbolizer NAME !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  if (Title.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some LineSymbolizer TITLE is warmly suggested\n\n");
+      msg += wxT("Do you really confirm leaving an empty (undefined) Title ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  if (Abstract.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some LineSymbolizer ABSTRACT is warmly suggested\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an empty (undefined) Abstract ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  return true;
+}
+
+bool SimpleLineSymbolizerDialog::RetrieveMainPage()
+{
+//
+// retrieving params from the MAIN page
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  Name = nameCtrl->GetValue();
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  Title = titleCtrl->GetValue();
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  Abstract = absCtrl->GetValue();
+  if (MinScale == true)
+    {
+      wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+      wxString value = minCtrl->GetValue();
+      if (value.ToDouble(&MinScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MinScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MaxScale == true)
+    {
+      wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+      wxString value = maxCtrl->GetValue();
+      if (value.ToDouble(&MaxScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MaxScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MinScale == true && MaxScale == true)
+    {
+      if (MinScaleDenominator >= MaxScaleDenominator)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE is always expected to be greater than MIN_SCALE !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  return true;
+}
+
+void SimpleLineSymbolizerDialog::UpdateMainPage()
+{
+//
+// updating the MAIN page
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  nameCtrl->SetValue(Name);
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  titleCtrl->SetValue(Title);
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  absCtrl->SetValue(Abstract);
+  wxRadioBox *uomBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_UOM);
+  switch (Uom)
+    {
+      case GUI_UOM_METRE:
+        uomBox->SetSelection(1);
+        break;
+      case GUI_UOM_INCH:
+        uomBox->SetSelection(2);
+        break;
+      default:
+        uomBox->SetSelection(0);
+        break;
+    };
+  wxRadioBox *rangeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  if (MinScale != true && MaxScale != true)
+    rangeBox->SetSelection(0);
+  else if (MinScale == true && MaxScale != true)
+    rangeBox->SetSelection(1);
+  else if (MinScale != true && MaxScale == true)
+    rangeBox->SetSelection(2);
+  else
+    rangeBox->SetSelection(3);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  char dummy[64];
+  wxString str;
+  if (MinScale == true)
+    {
+      sprintf(dummy, "%1.2f", MinScaleDenominator);
+      str = wxString::FromUTF8(dummy);
+      minCtrl->SetValue(str);
+      minCtrl->Enable(true);
+  } else
+    {
+      str = wxT("0.0");
+      minCtrl->SetValue(str);
+      minCtrl->Enable(false);
+    }
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  if (MaxScale == true)
+    {
+      sprintf(dummy, "%1.2f", MaxScaleDenominator);
+      str = wxString::FromUTF8(dummy);
+      maxCtrl->SetValue(str);
+      maxCtrl->Enable(true);
+  } else
+    {
+      str = wxT("+Infinite");
+      maxCtrl->SetValue(str);
+      maxCtrl->Enable(false);
+    }
+}
+
+bool SimpleLineSymbolizerDialog::DoParseDashArray(wxString & str, int which)
+{
+//
+// attempting to parse a Stroke DashArray string
+//
+  if (which == 0)
+    {
+      Stroke1DashCount = 0;
+      if (Stroke1DashArray != NULL)
+        delete[]Stroke1DashArray;
+      Stroke1DashArray = NULL;
+    }
+  if (which == 1)
+    {
+      Stroke2DashCount = 0;
+      if (Stroke2DashArray != NULL)
+        delete[]Stroke2DashArray;
+      Stroke2DashArray = NULL;
+    }
+  if (which == 2)
+    {
+      Stroke3DashCount = 0;
+      if (Stroke3DashArray != NULL)
+        delete[]Stroke3DashArray;
+      Stroke3DashArray = NULL;
+    }
+  if (str.Len() == 0)
+    return true;
+  int count = 0;
+  double interval;
+  wxStringTokenizer tkz(str, wxT(","));
+  while (tkz.HasMoreTokens())
+    {
+      wxString token = tkz.GetNextToken();
+      if (token.ToDouble(&interval) != true)
+        return false;
+      if (interval <= 0.0)
+        return false;
+      count++;
+    }
+  if (count == 0)
+    return true;
+  double *array;
+  if (which == 0)
+    {
+      Stroke1DashCount = count;
+      Stroke1DashArray = new double[Stroke1DashCount];
+      array = Stroke1DashArray;
+    }
+  if (which == 1)
+    {
+      Stroke2DashCount = count;
+      Stroke2DashArray = new double[Stroke2DashCount];
+      array = Stroke2DashArray;
+    }
+  if (which == 2)
+    {
+      Stroke3DashCount = count;
+      Stroke3DashArray = new double[Stroke3DashCount];
+      array = Stroke3DashArray;
+    }
+  count = 0;
+  wxStringTokenizer tkz2(str, wxT(","));
+  while (tkz2.HasMoreTokens())
+    {
+      wxString token = tkz2.GetNextToken();
+      token.ToDouble(&interval);
+      *(array + count++) = interval;
+    }
+  return true;
+}
+
+void SimpleLineSymbolizerDialog::NormalizedDashArray(wxString & str, int which,
+                                                     char delimiter)
+{
+//
+// creating a normalized DashArray string
+//
+  int count;
+  double *array;
+  if (which == 0)
+    {
+      count = Stroke1DashCount;
+      array = Stroke1DashArray;
+    }
+  if (which == 1)
+    {
+      count = Stroke2DashCount;
+      array = Stroke2DashArray;
+    }
+  if (which == 2)
+    {
+      count = Stroke3DashCount;
+      array = Stroke3DashArray;
+    }
+  str = wxT("");
+  if (count == 0)
+    return;
+  for (int i = 0; i < count; i++)
+    {
+      char dummy[64];
+      if (i == 0)
+        sprintf(dummy, "%1.2f", *(array + i));
+      else if (delimiter == ' ')
+        sprintf(dummy, " %1.2f", *(array + i));
+      else
+        sprintf(dummy, "%c %1.2f", delimiter, *(array + i));
+      str += wxString::FromUTF8(dummy);
+    }
+}
+
+bool SimpleLineSymbolizerDialog::RetrieveStroke1Page(bool check)
+{
+//
+// retrieving params from the STROKE #1 page
+//
+  wxSlider *opacityCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_STROKE1_OPACITY);
+  Stroke1Opacity = opacityCtrl->GetValue() / 100.0;
+  wxTextCtrl *perpCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_PERPENDICULAR);
+  wxString value = perpCtrl->GetValue();
+  if (value.ToDouble(&PerpendicularOffset1) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("PERPENDICULAR-OFFSET isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (HasGraphic1 == false)
+    {
+      wxTextCtrl *colorCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_COLOR);
+      wxString color = colorCtrl->GetValue();
+      if (ColorMapEntry::IsValidColor(color) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-COLOR isn't a valid HexRGB color !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      Stroke1Color = color;
+  } else
+    {
+      int selCount = 0;
+      int selected = -1;
+      for (int i = 0; i < GridCtrl1->GetNumberRows(); i++)
+        {
+          if (GridCtrl1->IsInSelection(i, 0) == true)
+            {
+              selected = i;
+              selCount++;
+            }
+        }
+      if (selCount < 1)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("You must select an External Graphic resource !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (selCount > 1)
+        {
+          if (check == true)
+            {
+              wxString msg =
+                wxT
+                ("You must select just a single External Graphic resource !!!\n");
+              msg += wxT("Multiple selection is not supported");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                           this);
+              return false;
+            }
+        }
+      List->FindByIndex(selected, Stroke1XLinkHref, Stroke1MimeType);
+      if (EnableStroke1Replacement == true)
+        {
+          wxTextCtrl *replacementCtrl =
+            (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_REPLACEMENT);
+          wxString color = replacementCtrl->GetValue();
+          if (ColorMapEntry::IsValidColor(color) != true)
+            {
+              if (check == true)
+                {
+                  wxMessageBox(wxT
+                               ("COLOR-REPACEMENT isn't a valid HexRGB color !!!"),
+                               wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                               this);
+                  return false;
+                }
+            }
+          Stroke1ColorReplacement = color;
+        }
+    }
+  wxTextCtrl *widthCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_WIDTH);
+  value = widthCtrl->GetValue();
+  if (value.ToDouble(&Stroke1Width) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-WIDTH isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (Stroke1Width <= 0.0)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-WIDTH must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *dashArrayCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_DASHARRAY);
+  value = dashArrayCtrl->GetValue();
+  if (DoParseDashArray(value, 0) == false)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-DASH-ARRAY: invalid expression !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+  } else
+    {
+      NormalizedDashArray(value, 0);
+      dashArrayCtrl->SetValue(value);
+    }
+  if (Stroke1DashCount == 0)
+    Stroke1DashOffset = 0.0;
+  else
+    {
+      wxTextCtrl *offsetCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_DASHOFFSET);
+      wxString value = offsetCtrl->GetValue();
+      if (value.ToDouble(&Stroke1DashOffset) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-DASH-OFFSET isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+    }
+  return true;
+}
+
+bool SimpleLineSymbolizerDialog::RetrieveStroke2Page(bool check)
+{
+//
+// retrieving params from the STROKE #2 page
+//
+  if (EnableStroke2 == false)
+    return true;
+  wxSlider *opacityCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_STROKE2_OPACITY);
+  Stroke2Opacity = opacityCtrl->GetValue() / 100.0;
+  wxTextCtrl *perpCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_PERPENDICULAR);
+  wxString value = perpCtrl->GetValue();
+  if (value.ToDouble(&PerpendicularOffset2) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("PERPENDICULAR-OFFSET isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (HasGraphic2 == false)
+    {
+      wxTextCtrl *colorCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_COLOR);
+      wxString color = colorCtrl->GetValue();
+      if (ColorMapEntry::IsValidColor(color) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-COLOR isn't a valid HexRGB color !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      Stroke2Color = color;
+  } else
+    {
+      int selCount = 0;
+      int selected = -1;
+      for (int i = 0; i < GridCtrl2->GetNumberRows(); i++)
+        {
+          if (GridCtrl2->IsInSelection(i, 0) == true)
+            {
+              selected = i;
+              selCount++;
+            }
+        }
+      if (selCount < 1)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("You must select an External Graphic resource !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (selCount > 1)
+        {
+          if (check == true)
+            {
+              wxString msg =
+                wxT
+                ("You must select just a single External Graphic resource !!!\n");
+              msg += wxT("Multiple selection is not supported");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                           this);
+              return false;
+            }
+        }
+      List->FindByIndex(selected, Stroke2XLinkHref, Stroke2MimeType);
+      if (EnableStroke2Replacement == true)
+        {
+          wxTextCtrl *replacementCtrl =
+            (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_REPLACEMENT);
+          wxString color = replacementCtrl->GetValue();
+          if (ColorMapEntry::IsValidColor(color) != true)
+            {
+              if (check == true)
+                {
+                  wxMessageBox(wxT
+                               ("COLOR-REPACEMENT isn't a valid HexRGB color !!!"),
+                               wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                               this);
+                  return false;
+                }
+            }
+          Stroke2ColorReplacement = color;
+        }
+    }
+  wxTextCtrl *widthCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_WIDTH);
+  value = widthCtrl->GetValue();
+  if (value.ToDouble(&Stroke2Width) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-WIDTH isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (Stroke2Width <= 0.0)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-WIDTH must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *dashArrayCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_DASHARRAY);
+  value = dashArrayCtrl->GetValue();
+  if (DoParseDashArray(value, 1) == false)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-DASH-ARRAY: invalid expression !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+  } else
+    {
+      NormalizedDashArray(value, 1);
+      dashArrayCtrl->SetValue(value);
+    }
+  if (Stroke2DashCount == 0)
+    Stroke2DashOffset = 0.0;
+  else
+    {
+      wxTextCtrl *offsetCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_DASHOFFSET);
+      wxString value = offsetCtrl->GetValue();
+      if (value.ToDouble(&Stroke2DashOffset) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-DASH-OFFSET isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+    }
+  return true;
+}
+
+bool SimpleLineSymbolizerDialog::RetrieveStroke3Page(bool check)
+{
+//
+// retrieving params from the STROKE #3 page
+//
+  if (EnableStroke2 == false)
+    return true;
+  wxSlider *opacityCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_STROKE3_OPACITY);
+  Stroke3Opacity = opacityCtrl->GetValue() / 100.0;
+  wxTextCtrl *perpCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_PERPENDICULAR);
+  wxString value = perpCtrl->GetValue();
+  if (value.ToDouble(&PerpendicularOffset3) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("PERPENDICULAR-OFFSET isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (HasGraphic3 == false)
+    {
+      wxTextCtrl *colorCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_COLOR);
+      wxString color = colorCtrl->GetValue();
+      if (ColorMapEntry::IsValidColor(color) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-COLOR isn't a valid HexRGB color !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      Stroke3Color = color;
+  } else
+    {
+      int selCount = 0;
+      int selected = -1;
+      for (int i = 0; i < GridCtrl3->GetNumberRows(); i++)
+        {
+          if (GridCtrl3->IsInSelection(i, 0) == true)
+            {
+              selected = i;
+              selCount++;
+            }
+        }
+      if (selCount < 1)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("You must select an External Graphic resource !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (selCount > 1)
+        {
+          if (check == true)
+            {
+              wxString msg =
+                wxT
+                ("You must select just a single External Graphic resource !!!\n");
+              msg += wxT("Multiple selection is not supported");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                           this);
+              return false;
+            }
+        }
+      List->FindByIndex(selected, Stroke3XLinkHref, Stroke3MimeType);
+      if (EnableStroke3Replacement == true)
+        {
+          wxTextCtrl *replacementCtrl =
+            (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_REPLACEMENT);
+          wxString color = replacementCtrl->GetValue();
+          if (ColorMapEntry::IsValidColor(color) != true)
+            {
+              if (check == true)
+                {
+                  wxMessageBox(wxT
+                               ("COLOR-REPACEMENT isn't a valid HexRGB color !!!"),
+                               wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                               this);
+                  return false;
+                }
+            }
+          Stroke3ColorReplacement = color;
+        }
+    }
+  wxTextCtrl *widthCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_WIDTH);
+  value = widthCtrl->GetValue();
+  if (value.ToDouble(&Stroke3Width) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-WIDTH isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (Stroke3Width <= 0.0)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-WIDTH must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *dashArrayCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_DASHARRAY);
+  value = dashArrayCtrl->GetValue();
+  if (DoParseDashArray(value, 2) == false)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-DASH-ARRAY: invalid expression !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+  } else
+    {
+      NormalizedDashArray(value, 2);
+      dashArrayCtrl->SetValue(value);
+    }
+  if (Stroke3DashCount == 0)
+    Stroke3DashOffset = 0.0;
+  else
+    {
+      wxTextCtrl *offsetCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_DASHOFFSET);
+      wxString value = offsetCtrl->GetValue();
+      if (value.ToDouble(&Stroke3DashOffset) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-DASH-OFFSET isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+    }
+  return true;
+}
+
+void SimpleLineSymbolizerDialog::UpdateStroke1Page()
+{
+//
+// updating the STROKE #1 page
+//
+  wxSlider *opacityCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_STROKE1_OPACITY);
+  opacityCtrl->SetValue(Stroke1Opacity * 100.0);
+  wxTextCtrl *perpCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_PERPENDICULAR);
+  char dummy[64];
+  sprintf(dummy, "%1.2f", PerpendicularOffset1);
+  wxString str = wxString::FromUTF8(dummy);
+  perpCtrl->SetValue(str);
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE1_TYPE);
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_PICKER_HEX);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_STROKE1_PICKER_BTN);
+  wxCheckBox *enableReplacement =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE1_ENABLE_REPLACEMENT);
+  wxTextCtrl *replacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_REPLACEMENT);
+  wxTextCtrl *sampleReplacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_REPLACEMENT_HEX);
+  if (HasGraphic1 == false)
+    {
+      typeBox->SetSelection(0);
+      colorCtrl->Enable(true);
+      sampleCtrl->Enable(true);
+      pick->Enable(true);
+      GridCtrl1->Enable(false);
+      GridCtrl1->ClearSelection();
+      wxColour color = wxNullColour;
+      ColorMapEntry::GetWxColor(Stroke1Color, color);
+      if (color.IsOk() == true)
+        {
+          char hex[16];
+          sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                  color.Blue());
+          wxString str = wxString::FromUTF8(hex);
+          colorCtrl->SetValue(str);
+        }
+      enableReplacement->Enable(false);
+      replacementCtrl->Enable(false);
+  } else
+    {
+      typeBox->SetSelection(1);
+      colorCtrl->Enable(false);
+      sampleCtrl->Enable(false);
+      pick->Enable(false);
+      GridCtrl1->Enable(true);
+      int sel = List->FindByXLinkHref(Stroke1XLinkHref);
+      if (sel >= 0)
+        GridCtrl1->SelectRow(sel);
+      enableReplacement->Enable(true);
+      if (EnableStroke1Replacement == true)
+        {
+          wxColour color = wxNullColour;
+          ColorMapEntry::GetWxColor(Stroke1ColorReplacement, color);
+          if (color.IsOk() == true)
+            {
+              char hex[16];
+              sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                      color.Blue());
+              wxString str = wxString::FromUTF8(hex);
+              replacementCtrl->SetValue(str);
+              replacementCtrl->Enable(true);
+          } else
+            replacementCtrl->Enable(false);
+        }
+    }
+  wxTextCtrl *widthCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_WIDTH);
+  sprintf(dummy, "%1.2f", Stroke1Width);
+  str = wxString::FromUTF8(dummy);
+  widthCtrl->SetValue(str);
+  wxRadioBox *lineJoinCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE1_LINEJOIN);
+  switch (Stroke1LineJoin)
+    {
+      case RL2_PEN_JOIN_MITER:
+        lineJoinCtrl->SetSelection(0);
+        break;
+      case RL2_PEN_JOIN_BEVEL:
+        lineJoinCtrl->SetSelection(2);
+        break;
+      default:
+        lineJoinCtrl->SetSelection(1);
+        break;
+    };
+  wxRadioBox *lineCapCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE1_LINECAP);
+  switch (Stroke1LineCap)
+    {
+      case RL2_PEN_CAP_BUTT:
+        lineCapCtrl->SetSelection(0);
+        break;
+      case RL2_PEN_CAP_SQUARE:
+        lineCapCtrl->SetSelection(2);
+        break;
+      default:
+        lineCapCtrl->SetSelection(1);
+        break;
+    };
+  wxTextCtrl *dashArrayCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_DASHARRAY);
+  wxString value;
+  NormalizedDashArray(value, 0);
+  dashArrayCtrl->SetValue(value);
+  wxTextCtrl *offsetCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_DASHOFFSET);
+  if (Stroke1DashCount == 0)
+    offsetCtrl->SetValue(wxT("0.0"));
+  else
+    {
+      sprintf(dummy, "%1.2f", Stroke1DashOffset);
+      str = wxString::FromUTF8(dummy);
+      offsetCtrl->SetValue(str);
+    }
+}
+
+void SimpleLineSymbolizerDialog::UpdateStroke2Page()
+{
+//
+// updating the STROKE #2 page
+//
+  wxCheckBox *enableBox =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE2_ENABLE);
+  if (EnableStroke2 == true)
+    enableBox->SetValue(true);
+  else
+    enableBox->SetValue(false);
+  wxSlider *opacityCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_STROKE2_OPACITY);
+  opacityCtrl->SetValue(Stroke2Opacity * 100.0);
+  if (EnableStroke2 == false)
+    opacityCtrl->Enable(false);
+  else
+    opacityCtrl->Enable(true);
+  wxTextCtrl *perpCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_PERPENDICULAR);
+  char dummy[64];
+  sprintf(dummy, "%1.2f", PerpendicularOffset2);
+  wxString str = wxString::FromUTF8(dummy);
+  perpCtrl->SetValue(str);
+  if (EnableStroke2 == false)
+    perpCtrl->Enable(false);
+  else
+    perpCtrl->Enable(true);
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE2_TYPE);
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_PICKER_HEX);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_STROKE2_PICKER_BTN);
+  wxCheckBox *enableReplacement =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE2_ENABLE_REPLACEMENT);
+  wxTextCtrl *replacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_REPLACEMENT);
+  wxTextCtrl *sampleReplacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_REPLACEMENT_HEX);
+  if (EnableStroke2 == false)
+    {
+      typeBox->Enable(false);
+      colorCtrl->Enable(false);
+      sampleCtrl->Enable(false);
+      pick->Enable(false);
+      enableReplacement->Enable(false);
+      replacementCtrl->Enable(false);
+  } else
+    {
+      typeBox->Enable(true);
+      if (HasGraphic2 == false)
+        {
+          typeBox->SetSelection(0);
+          colorCtrl->Enable(true);
+          sampleCtrl->Enable(true);
+          pick->Enable(true);
+          GridCtrl2->Enable(false);
+          GridCtrl2->ClearSelection();
+          wxColour color = wxNullColour;
+          ColorMapEntry::GetWxColor(Stroke2Color, color);
+          if (color.IsOk() == true)
+            {
+              char hex[16];
+              sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                      color.Blue());
+              wxString str = wxString::FromUTF8(hex);
+              colorCtrl->SetValue(str);
+            }
+          enableReplacement->Enable(false);
+          replacementCtrl->Enable(false);
+      } else
+        {
+          typeBox->SetSelection(1);
+          colorCtrl->Enable(false);
+          sampleCtrl->Enable(false);
+          pick->Enable(false);
+          GridCtrl2->Enable(true);
+          int sel = List->FindByXLinkHref(Stroke2XLinkHref);
+          if (sel >= 0)
+            GridCtrl2->SelectRow(sel);
+          enableReplacement->Enable(true);
+          if (EnableStroke2Replacement == true)
+            {
+              wxColour color = wxNullColour;
+              ColorMapEntry::GetWxColor(Stroke2ColorReplacement, color);
+              if (color.IsOk() == true)
+                {
+                  char hex[16];
+                  sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                          color.Blue());
+                  wxString str = wxString::FromUTF8(hex);
+                  replacementCtrl->SetValue(str);
+                  replacementCtrl->Enable(true);
+              } else
+                replacementCtrl->Enable(false);
+            }
+        }
+    }
+  wxTextCtrl *widthCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_WIDTH);
+  sprintf(dummy, "%1.2f", Stroke2Width);
+  str = wxString::FromUTF8(dummy);
+  widthCtrl->SetValue(str);
+  if (EnableStroke2 == false)
+    widthCtrl->Enable(false);
+  else
+    widthCtrl->Enable(true);
+  wxRadioBox *lineJoinCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE2_LINEJOIN);
+  switch (Stroke2LineJoin)
+    {
+      case RL2_PEN_JOIN_MITER:
+        lineJoinCtrl->SetSelection(0);
+        break;
+      case RL2_PEN_JOIN_BEVEL:
+        lineJoinCtrl->SetSelection(2);
+        break;
+      default:
+        lineJoinCtrl->SetSelection(1);
+        break;
+    };
+  if (EnableStroke2 == false)
+    lineJoinCtrl->Enable(false);
+  else
+    lineJoinCtrl->Enable(true);
+  wxRadioBox *lineCapCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE2_LINECAP);
+  switch (Stroke2LineCap)
+    {
+      case RL2_PEN_CAP_BUTT:
+        lineCapCtrl->SetSelection(0);
+        break;
+      case RL2_PEN_CAP_SQUARE:
+        lineCapCtrl->SetSelection(2);
+        break;
+      default:
+        lineCapCtrl->SetSelection(1);
+        break;
+    };
+  if (EnableStroke2 == false)
+    lineCapCtrl->Enable(false);
+  else
+    lineCapCtrl->Enable(true);
+  wxTextCtrl *dashArrayCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_DASHARRAY);
+  wxString value;
+  NormalizedDashArray(value, 1);
+  dashArrayCtrl->SetValue(value);
+  if (EnableStroke2 == false)
+    dashArrayCtrl->Enable(false);
+  else
+    dashArrayCtrl->Enable(true);
+  wxTextCtrl *offsetCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_DASHOFFSET);
+  if (Stroke2DashCount == 0)
+    offsetCtrl->SetValue(wxT("0.0"));
+  else
+    {
+      char dummy[64];
+      sprintf(dummy, "%1.2f", Stroke2DashOffset);
+      wxString str = wxString::FromUTF8(dummy);
+      offsetCtrl->SetValue(str);
+    }
+  if (EnableStroke2 == false)
+    offsetCtrl->Enable(false);
+  else
+    offsetCtrl->Enable(true);
+}
+
+void SimpleLineSymbolizerDialog::UpdateStroke3Page()
+{
+//
+// updating the STROKE #3 page
+//
+  wxCheckBox *enableBox =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE3_ENABLE);
+  if (EnableStroke3 == true)
+    enableBox->SetValue(true);
+  else
+    enableBox->SetValue(false);
+  wxSlider *opacityCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_STROKE3_OPACITY);
+  opacityCtrl->SetValue(Stroke3Opacity * 100.0);
+  if (EnableStroke3 == false)
+    opacityCtrl->Enable(false);
+  else
+    opacityCtrl->Enable(true);
+  wxTextCtrl *perpCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_PERPENDICULAR);
+  char dummy[64];
+  sprintf(dummy, "%1.2f", PerpendicularOffset3);
+  wxString str = wxString::FromUTF8(dummy);
+  perpCtrl->SetValue(str);
+  if (EnableStroke3 == false)
+    perpCtrl->Enable(false);
+  else
+    perpCtrl->Enable(true);
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE3_TYPE);
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_PICKER_HEX);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_STROKE3_PICKER_BTN);
+  wxCheckBox *enableReplacement =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE3_ENABLE_REPLACEMENT);
+  wxTextCtrl *replacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_REPLACEMENT);
+  wxTextCtrl *sampleReplacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_REPLACEMENT_HEX);
+  if (EnableStroke3 == false)
+    {
+      typeBox->Enable(false);
+      colorCtrl->Enable(false);
+      sampleCtrl->Enable(false);
+      pick->Enable(false);
+      enableReplacement->Enable(false);
+      replacementCtrl->Enable(false);
+  } else
+    {
+      typeBox->Enable(true);
+      if (HasGraphic3 == false)
+        {
+          typeBox->SetSelection(0);
+          colorCtrl->Enable(true);
+          sampleCtrl->Enable(true);
+          pick->Enable(true);
+          GridCtrl3->Enable(false);
+          GridCtrl3->ClearSelection();
+          wxColour color = wxNullColour;
+          ColorMapEntry::GetWxColor(Stroke3Color, color);
+          if (color.IsOk() == true)
+            {
+              char hex[16];
+              sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                      color.Blue());
+              wxString str = wxString::FromUTF8(hex);
+              colorCtrl->SetValue(str);
+            }
+          enableReplacement->Enable(false);
+          replacementCtrl->Enable(false);
+      } else
+        {
+          typeBox->SetSelection(1);
+          colorCtrl->Enable(false);
+          sampleCtrl->Enable(false);
+          pick->Enable(false);
+          GridCtrl3->Enable(true);
+          int sel = List->FindByXLinkHref(Stroke3XLinkHref);
+          if (sel >= 0)
+            GridCtrl3->SelectRow(sel);
+          enableReplacement->Enable(true);
+          if (EnableStroke3Replacement == true)
+            {
+              wxColour color = wxNullColour;
+              ColorMapEntry::GetWxColor(Stroke3ColorReplacement, color);
+              if (color.IsOk() == true)
+                {
+                  char hex[16];
+                  sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                          color.Blue());
+                  wxString str = wxString::FromUTF8(hex);
+                  replacementCtrl->SetValue(str);
+                  replacementCtrl->Enable(true);
+              } else
+                replacementCtrl->Enable(false);
+            }
+        }
+    }
+  wxTextCtrl *widthCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_WIDTH);
+  sprintf(dummy, "%1.2f", Stroke3Width);
+  str = wxString::FromUTF8(dummy);
+  widthCtrl->SetValue(str);
+  if (EnableStroke3 == false)
+    widthCtrl->Enable(false);
+  else
+    widthCtrl->Enable(true);
+  wxRadioBox *lineJoinCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE3_LINEJOIN);
+  switch (Stroke3LineJoin)
+    {
+      case RL2_PEN_JOIN_MITER:
+        lineJoinCtrl->SetSelection(0);
+        break;
+      case RL2_PEN_JOIN_BEVEL:
+        lineJoinCtrl->SetSelection(2);
+        break;
+      default:
+        lineJoinCtrl->SetSelection(1);
+        break;
+    };
+  if (EnableStroke3 == false)
+    lineJoinCtrl->Enable(false);
+  else
+    lineJoinCtrl->Enable(true);
+  wxRadioBox *lineCapCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE3_LINECAP);
+  switch (Stroke3LineCap)
+    {
+      case RL2_PEN_CAP_BUTT:
+        lineCapCtrl->SetSelection(0);
+        break;
+      case RL2_PEN_CAP_SQUARE:
+        lineCapCtrl->SetSelection(2);
+        break;
+      default:
+        lineCapCtrl->SetSelection(1);
+        break;
+    };
+  if (EnableStroke3 == false)
+    lineCapCtrl->Enable(false);
+  else
+    lineCapCtrl->Enable(true);
+  wxTextCtrl *dashArrayCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_DASHARRAY);
+  wxString value;
+  NormalizedDashArray(value, 2);
+  dashArrayCtrl->SetValue(value);
+  if (EnableStroke3 == false)
+    dashArrayCtrl->Enable(false);
+  else
+    dashArrayCtrl->Enable(true);
+  wxTextCtrl *offsetCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE3_DASHOFFSET);
+  if (Stroke3DashCount == 0)
+    offsetCtrl->SetValue(wxT("0.0"));
+  else
+    {
+      char dummy[64];
+      sprintf(dummy, "%1.2f", Stroke3DashOffset);
+      wxString str = wxString::FromUTF8(dummy);
+      offsetCtrl->SetValue(str);
+    }
+  if (EnableStroke3 == false)
+    offsetCtrl->Enable(false);
+  else
+    offsetCtrl->Enable(true);
+}
+
+bool SimpleLineSymbolizerDialog::RetrievePreviewPage()
+{
+//
+// retrieving params from the PREVIEW page
+//
+  return true;
+}
+
+void SimpleLineSymbolizerDialog::PrepareLinestringPath(void *xctx,
+                                                       double
+                                                       perpendicular_offset)
+{
+// Visual Preview
+  gaiaDynamicLinePtr dyn = gaiaAllocDynamicLine();
+  gaiaAppendPointToDynamicLine(dyn, 210.0, 80.0);
+  gaiaAppendPointToDynamicLine(dyn, 210.0, 150.0);
+  gaiaAppendPointToDynamicLine(dyn, 175.0, 150.0);
+  double pi = 3.14159265359;
+  for (double rads = (2.0 * pi) - (pi / 2.0); rads >= 0.0; rads -= 0.666666)
+    {
+      double x = 135.0 + (115.0 * cos(rads));
+      double y = 150.0 + (115.0 * sin(rads));
+      gaiaAppendPointToDynamicLine(dyn, x, y);
+    }
+  for (double rads = pi; rads <= (pi * 2.0) + (pi / 2.0); rads += 0.1)
+    {
+      double x = 365.0 + (115.0 * cos(rads));
+      double y = 150.0 + (115.0 * sin(rads));
+      gaiaAppendPointToDynamicLine(dyn, x, y);
+    }
+  gaiaAppendPointToDynamicLine(dyn, 365.0, 150.0);
+  gaiaAppendPointToDynamicLine(dyn, 340.0, 200.0);
+  gaiaAppendPointToDynamicLine(dyn, 310.0, 200.0);
+  gaiaAppendPointToDynamicLine(dyn, 310.0, 100.0);
+  gaiaAppendPointToDynamicLine(dyn, 410.0, 100.0);
+  gaiaAppendPointToDynamicLine(dyn, 410.0, 200.0);
+
+  int points = 0;
+  gaiaPointPtr pt = dyn->First;
+  while (pt != NULL)
+    {
+      // counting how many Points are there
+      points++;
+      pt = pt->Next;
+    }
+  gaiaGeomCollPtr geom = gaiaAllocGeomColl();
+  gaiaLinestringPtr ln = gaiaAddLinestringToGeomColl(geom, points);
+  int iv = 0;
+  pt = dyn->First;
+  while (pt != NULL)
+    {
+      // preparing the Linestring
+      gaiaSetPoint(ln->Coords, iv, pt->X, pt->Y);
+      iv++;
+      pt = pt->Next;
+    }
+  gaiaFreeDynamicLine(dyn);
+
+  gaiaGeomCollPtr geom2;
+  if (perpendicular_offset != 0.0)
+    {
+      // Offset Curve
+      geom2 =
+        gaiaOffsetCurve_r(MainFrame->GetSpliteInternalCache(), geom,
+                          perpendicular_offset, 16, 0);
+      gaiaFreeGeomColl(geom);
+  } else
+    {
+      // unchanged
+      geom2 = geom;
+    }
+
+// preparing the Line Path
+  ln = geom2->FirstLinestring;
+  rl2GraphicsContextPtr ctx = (rl2GraphicsContextPtr) xctx;
+  for (iv = 0; iv < ln->Points; iv++)
+    {
+      double x;
+      double y;
+      gaiaGetPoint(ln->Coords, iv, &x, &y);
+      if (iv == 0)
+        rl2_graph_move_to_point(ctx, x, y);
+      else
+        rl2_graph_add_line_to_path(ctx, x, y);
+    }
+  gaiaFreeGeomColl(geom2);
+}
+
+void SimpleLineSymbolizerDialog::UpdatePreviewPage()
+{
+//
+// updating the PREVIEW page
+//
+  rl2GraphicsPatternPtr pattern1 = NULL;
+  rl2GraphicsPatternPtr pattern2 = NULL;
+  rl2GraphicsPatternPtr pattern3 = NULL;
+  wxRadioBox *backCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_BACKGROUND);
+  switch (PreviewBackground)
+    {
+      case GUI_PREVIEW_BACKGROUND_WHITE:
+        backCtrl->SetSelection(1);
+        break;
+      case GUI_PREVIEW_BACKGROUND_BLACK:
+        backCtrl->SetSelection(2);
+        break;
+      default:
+        backCtrl->SetSelection(0);
+        break;
+    };
+  rl2GraphicsContextPtr ctx = NULL;
+  ctx = rl2_graph_create_context(500, 300);
+  if (ctx == NULL)
+    return;
+// transparent background initialization
+  rl2_graph_set_brush(ctx, 255, 255, 255, 0);
+  rl2_graph_draw_rectangle(ctx, -1, -1, 501, 301);
+
+  if (HasGraphic1 == false)
+    {
+      // preparing a Color-based Pen
+      double aleph = 255.0 * Stroke1Opacity;
+      if (aleph < 0.0)
+        aleph = 0.0;
+      if (aleph > 255.0)
+        aleph = 255.0;
+      unsigned char alpha = aleph;
+      wxColour color = wxNullColour;
+      ColorMapEntry::GetWxColor(Stroke1Color, color);
+      if (Stroke1DashCount == 0)
+        rl2_graph_set_solid_pen(ctx, color.Red(), color.Green(), color.Blue(),
+                                alpha, Stroke1Width, Stroke1LineCap,
+                                Stroke1LineJoin);
+      else
+        rl2_graph_set_dashed_pen(ctx, color.Red(), color.Green(), color.Blue(),
+                                 alpha, Stroke1Width, Stroke1LineCap,
+                                 Stroke1LineJoin, Stroke1DashCount,
+                                 Stroke1DashArray, Stroke1DashOffset);
+  } else
+    {
+      // preparing a Pattern-based Pen
+      pattern1 =
+        rl2_create_pattern_from_external_graphic(MainFrame->GetSqlite(),
+                                                 Stroke1XLinkHref.ToUTF8(), 1);
+      if (pattern1 != NULL)
+        {
+          if (EnableStroke1Replacement)
+            {
+              // attempting to recolor the External Graphic resource
+              wxColour color = wxNullColour;
+              ColorMapEntry::GetWxColor(Stroke1ColorReplacement, color);
+              rl2_graph_pattern_recolor(pattern1, color.Red(), color.Green(),
+                                        color.Blue());
+            }
+          if (Stroke1Opacity < 1.0)
+            {
+              // setting up the required transparency
+              double aleph = 255.0 * Stroke1Opacity;
+              if (aleph < 0.0)
+                aleph = 0.0;
+              if (aleph > 255.0)
+                aleph = 255.0;
+              unsigned char alpha = aleph;
+              rl2_graph_pattern_transparency(pattern1, alpha);
+            }
+          if (Stroke1DashCount == 0)
+            rl2_graph_set_pattern_solid_pen(ctx, pattern1, Stroke1Width,
+                                            Stroke1LineCap, Stroke1LineJoin);
+          else
+            rl2_graph_set_pattern_dashed_pen(ctx, pattern1, Stroke1Width,
+                                             Stroke1LineCap, Stroke1LineJoin,
+                                             Stroke1DashCount, Stroke1DashArray,
+                                             Stroke1DashOffset);
+      } else
+        {
+          // invalid Pattern: defaulting to a black Pen
+          if (Stroke1DashCount == 0)
+            rl2_graph_set_solid_pen(ctx, 0, 0, 0, 255, Stroke1Width,
+                                    Stroke1LineCap, Stroke1LineJoin);
+          else
+            rl2_graph_set_dashed_pen(ctx, 0, 0, 0, 255, Stroke1Width,
+                                     Stroke1LineCap, Stroke1LineJoin,
+                                     Stroke1DashCount, Stroke1DashArray,
+                                     Stroke1DashOffset);
+        }
+    }
+
+// applying the Stroke #1
+  PrepareLinestringPath(ctx, PerpendicularOffset1);
+  rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
+
+  if (EnableStroke2 == true)
+    {
+      // applying the Stroke #2
+      if (HasGraphic2 == false)
+        {
+          // preparing a Color-based Pen
+          double aleph = 255.0 * Stroke2Opacity;
+          if (aleph < 0.0)
+            aleph = 0.0;
+          if (aleph > 255.0)
+            aleph = 255.0;
+          unsigned char alpha = aleph;
+          wxColour color = wxNullColour;
+          ColorMapEntry::GetWxColor(Stroke2Color, color);
+          if (Stroke2DashCount == 0)
+            rl2_graph_set_solid_pen(ctx, color.Red(), color.Green(),
+                                    color.Blue(), alpha, Stroke2Width,
+                                    Stroke2LineCap, Stroke2LineJoin);
+          else
+            rl2_graph_set_dashed_pen(ctx, color.Red(), color.Green(),
+                                     color.Blue(), alpha, Stroke2Width,
+                                     Stroke2LineCap, Stroke2LineJoin,
+                                     Stroke2DashCount, Stroke2DashArray,
+                                     Stroke2DashOffset);
+      } else
+        {
+          // preparing a Pattern-based Pen
+          pattern2 =
+            rl2_create_pattern_from_external_graphic(MainFrame->GetSqlite(),
+                                                     Stroke2XLinkHref.ToUTF8(),
+                                                     1);
+          if (pattern2 != NULL)
+            {
+              if (EnableStroke2Replacement)
+                {
+                  // attempting to recolor the External Graphic resource
+                  wxColour color = wxNullColour;
+                  ColorMapEntry::GetWxColor(Stroke2ColorReplacement, color);
+                  rl2_graph_pattern_recolor(pattern2, color.Red(),
+                                            color.Green(), color.Blue());
+                }
+              if (Stroke2Opacity < 1.0)
+                {
+                  // setting up the required transparency
+                  double aleph = 255.0 * Stroke2Opacity;
+                  if (aleph < 0.0)
+                    aleph = 0.0;
+                  if (aleph > 255.0)
+                    aleph = 255.0;
+                  unsigned char alpha = aleph;
+                  rl2_graph_pattern_transparency(pattern2, alpha);
+                }
+              if (Stroke2DashCount == 0)
+                rl2_graph_set_pattern_solid_pen(ctx, pattern2, Stroke2Width,
+                                                Stroke2LineCap,
+                                                Stroke2LineJoin);
+              else
+                rl2_graph_set_pattern_dashed_pen(ctx, pattern2, Stroke2Width,
+                                                 Stroke2LineCap,
+                                                 Stroke2LineJoin,
+                                                 Stroke2DashCount,
+                                                 Stroke2DashArray,
+                                                 Stroke2DashOffset);
+          } else
+            {
+              // invalid Pattern: defaulting to a black Pen
+              if (Stroke2DashCount == 0)
+                rl2_graph_set_solid_pen(ctx, 0, 0, 0, 255, Stroke2Width,
+                                        Stroke2LineCap, Stroke2LineJoin);
+              else
+                rl2_graph_set_dashed_pen(ctx, 0, 0, 0, 255, Stroke2Width,
+                                         Stroke2LineCap, Stroke2LineJoin,
+                                         Stroke2DashCount, Stroke2DashArray,
+                                         Stroke2DashOffset);
+            }
+        }
+      PrepareLinestringPath(ctx, PerpendicularOffset2);
+      rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
+    }
+
+  if (EnableStroke3 == true)
+    {
+      // applying the Stroke #3
+      if (HasGraphic3 == false)
+        {
+          // preparing a Color-based Pen
+          double aleph = 255.0 * Stroke3Opacity;
+          if (aleph < 0.0)
+            aleph = 0.0;
+          if (aleph > 255.0)
+            aleph = 255.0;
+          unsigned char alpha = aleph;
+          wxColour color = wxNullColour;
+          ColorMapEntry::GetWxColor(Stroke3Color, color);
+          if (Stroke3DashCount == 0)
+            rl2_graph_set_solid_pen(ctx, color.Red(), color.Green(),
+                                    color.Blue(), alpha, Stroke3Width,
+                                    Stroke3LineCap, Stroke3LineJoin);
+          else
+            rl2_graph_set_dashed_pen(ctx, color.Red(), color.Green(),
+                                     color.Blue(), alpha, Stroke3Width,
+                                     Stroke3LineCap, Stroke3LineJoin,
+                                     Stroke3DashCount, Stroke3DashArray,
+                                     Stroke3DashOffset);
+      } else
+        {
+          // preparing a Pattern-based Pen
+          pattern3 =
+            rl2_create_pattern_from_external_graphic(MainFrame->GetSqlite(),
+                                                     Stroke3XLinkHref.ToUTF8(),
+                                                     1);
+          if (pattern3 != NULL)
+            {
+              if (EnableStroke3Replacement)
+                {
+                  // attempting to recolor the External Graphic resource
+                  wxColour color = wxNullColour;
+                  ColorMapEntry::GetWxColor(Stroke3ColorReplacement, color);
+                  rl2_graph_pattern_recolor(pattern3, color.Red(),
+                                            color.Green(), color.Blue());
+                }
+              if (Stroke3Opacity < 1.0)
+                {
+                  // setting up the required transparency
+                  double aleph = 255.0 * Stroke3Opacity;
+                  if (aleph < 0.0)
+                    aleph = 0.0;
+                  if (aleph > 255.0)
+                    aleph = 255.0;
+                  unsigned char alpha = aleph;
+                  rl2_graph_pattern_transparency(pattern3, alpha);
+                }
+              if (Stroke3DashCount == 0)
+                rl2_graph_set_pattern_solid_pen(ctx, pattern3, Stroke3Width,
+                                                Stroke3LineCap,
+                                                Stroke3LineJoin);
+              else
+                rl2_graph_set_pattern_dashed_pen(ctx, pattern3, Stroke3Width,
+                                                 Stroke3LineCap,
+                                                 Stroke3LineJoin,
+                                                 Stroke3DashCount,
+                                                 Stroke3DashArray,
+                                                 Stroke3DashOffset);
+          } else
+            {
+              // invalid Pattern: defaulting to a black Pen
+              if (Stroke3DashCount == 0)
+                rl2_graph_set_solid_pen(ctx, 0, 0, 0, 255, Stroke3Width,
+                                        Stroke3LineCap, Stroke3LineJoin);
+              else
+                rl2_graph_set_dashed_pen(ctx, 0, 0, 0, 255, Stroke3Width,
+                                         Stroke3LineCap, Stroke3LineJoin,
+                                         Stroke3DashCount, Stroke3DashArray,
+                                         Stroke3DashOffset);
+            }
+        }
+      PrepareLinestringPath(ctx, PerpendicularOffset3);
+      rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
+    }
+// creating the RGB and Alpha arrays
+  int half_transparency = 0;
+  unsigned char *rgb_array = rl2_graph_get_context_rgb_array(ctx);
+  unsigned char *alpha_array =
+    rl2_graph_get_context_alpha_array(ctx, &half_transparency);
+  rl2_graph_destroy_context(ctx);
+  if (pattern1 != NULL)
+    rl2_graph_destroy_pattern(pattern1);
+  if (pattern2 != NULL)
+    rl2_graph_destroy_pattern(pattern2);
+  if (pattern3 != NULL)
+    rl2_graph_destroy_pattern(pattern3);
+  if (rgb_array == NULL || alpha_array == NULL)
+    {
+      if (rgb_array != NULL)
+        free(rgb_array);
+      if (alpha_array != NULL)
+        free(alpha_array);
+      return;
+    }
+// creating the Preview from RGB and Alpha arrays
+  wxImage img(500, 300);
+  img.SetData(rgb_array);
+  img.SetAlpha(alpha_array);
+  wxBitmap bmp(img);
+  wxBitmap bmp2;
+  wxBrush brush;
+  wxMemoryDC dc;
+  wxBitmap white = wxBitmap(500, 300);
+  wxBitmap black = wxBitmap(500, 300);
+  switch (PreviewBackground)
+    {
+      case GUI_PREVIEW_BACKGROUND_WHITE:
+        dc.SelectObject(white);
+        brush = wxBrush(wxColour(255, 255, 255));
+        dc.SetBrush(brush);
+        dc.DrawRectangle(0, 0, 500, 300);
+        dc.SelectObject(wxNullBitmap);
+        bmp2 =
+          white.GetSubBitmap(wxRect(0, 0, white.GetWidth(), white.GetHeight()));
+        break;
+      case GUI_PREVIEW_BACKGROUND_BLACK:
+        dc.SelectObject(black);
+        brush = wxBrush(wxColour(0, 0, 0));
+        dc.SetBrush(brush);
+        dc.DrawRectangle(0, 0, 500, 300);
+        dc.SelectObject(wxNullBitmap);
+        bmp2 =
+          black.GetSubBitmap(wxRect(0, 0, black.GetWidth(), black.GetHeight()));
+        break;
+      default:
+        bmp2 =
+          PreviewBackBitmap.GetSubBitmap(wxRect
+                                         (0, 0, PreviewBackBitmap.GetWidth(),
+                                          PreviewBackBitmap.GetHeight()));
+        break;
+    };
+// printing the Preview over the currently selected background
+  dc.SelectObject(bmp2);
+  dc.DrawBitmap(bmp, 0, 0, true);
+  dc.SelectObject(wxNullBitmap);
+// updating the GUI Preview
+  SymbolizerPreview *previewCtrl =
+    (SymbolizerPreview *) FindWindow(ID_SYMBOLIZER_PREVIEW);
+  previewCtrl->SetBitmap(bmp2);
+}
+
+void SimpleLineSymbolizerDialog::OnPageChanging(wxNotebookEvent & event)
+{
+//
+// TAB/PAGE selection changing
+//
+  bool ret;
+  switch (event.GetOldSelection())
+    {
+      case 0:
+        ret = RetrieveMainPage();
+        break;
+      case 1:
+        ret = RetrieveStroke1Page();
+        break;
+      case 2:
+        ret = RetrieveStroke2Page();
+        break;
+      case 3:
+        ret = RetrieveStroke3Page();
+        break;
+      case 4:
+        ret = RetrievePreviewPage();
+        break;
+    };
+  if (ret != true)
+    event.Veto();
+}
+
+void SimpleLineSymbolizerDialog::OnPageChanged(wxNotebookEvent & event)
+{
+//
+// TAB/PAGE selection changed
+//
+  switch (event.GetSelection())
+    {
+      case 0:
+        UpdateMainPage();
+        break;
+      case 1:
+        UpdateStroke1Page();
+        break;
+      case 2:
+        UpdateStroke2Page();
+        break;
+      case 3:
+        UpdateStroke3Page();
+        break;
+      case 4:
+        UpdatePreviewPage();
+        break;
+    };
+}
+
+char *SimpleLineSymbolizerDialog::DoCreateFeatureTypeXML()
+{
+//
+// creating the SLD/SE (XML) code - Feature Type
+//
+  char *str;
+  const char *cstr;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<FeatureTypeStyle version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Rule>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (MinScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MinScaleDenominator>%1.2f</MinScaleDenominator>\r\n", prev,
+         MinScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MaxScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MaxScaleDenominator>%1.2f</MaxScaleDenominator>\r\n", prev,
+         MaxScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  switch (Uom)
+    {
+      case GUI_UOM_METRE:
+        cstr = "http://www.opengeospatial.org/se/units/metre";
+        break;
+      case GUI_UOM_INCH:
+        cstr = "http://www.opengeospatial.org/se/units/inch";
+        break;
+      default:
+        cstr = "http://www.opengeospatial.org/se/units/pixel";
+        break;
+    };
+  xml = sqlite3_mprintf("%s\t\t<LineSymbolizer uom=\"%s\">\r\n", prev, cstr);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<Stroke>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (HasGraphic1 == true)
+    {
+      // using an External Graphic
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<GraphicStroke>\r\n\t\t\t\t\t<Graphic>\r\n\t\t\t\t\t\t<ExternalGraphic>\r\n",
+         prev);
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(Stroke1XLinkHref.ToUTF8()) + 1];
+      strcpy(str, Stroke1XLinkHref.ToUTF8());
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t\t\t\t<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\" />\r\n",
+         prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(Stroke1MimeType.ToUTF8()) + 1];
+      strcpy(str, Stroke1MimeType.ToUTF8());
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t\t\t\t<Format>%s</Format>\r\n", prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      if (EnableStroke1Replacement == true)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t<ColorReplacement>\r\n\t\t\t\t\t\t\t\t<Recode fallbackValue=\"#000000\">\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t\t\t<LookupValue>ExternalGraphic</LookupValue>\r\n\t\t\t\t\t\t\t\t\t<MapItem>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Stroke1ColorReplacement.ToUTF8()) + 1];
+          strcpy(str, Stroke1ColorReplacement.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t\t\t\t<Data>1</Data>\r\n\t\t\t\t\t\t\t\t\t\t<Value>%s</Value>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t\t\t</MapItem>\r\n\t\t\t\t\t\t\t</Recode>\r\n\t\t\t\t\t\t\t</ColorReplacement>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t\t\t</ExternalGraphic>\r\n\t\t\t\t\t</Graphic>\r\n\t\t\t\t</GraphicStroke>\r\n",
+         prev);
+      sqlite3_free(prev);
+      prev = xml;
+  } else
+    {
+      // using a Solid Color
+      str = new char[strlen(Stroke1Color.ToUTF8()) + 1];
+      strcpy(str, Stroke1Color.ToUTF8());
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<SvgParameter name=\"stroke\">%s</SvgParameter>\r\n", prev,
+         str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t\t\t<SvgParameter name=\"stroke-opacity\">%1.2f</SvgParameter>\r\n",
+     prev, Stroke1Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t\t\t<SvgParameter name=\"stroke-width\">%1.2f</SvgParameter>\r\n",
+     prev, Stroke1Width);
+  sqlite3_free(prev);
+  prev = xml;
+  switch (Stroke1LineJoin)
+    {
+      case RL2_PEN_JOIN_MITER:
+        xml =
+          sqlite3_mprintf
+          ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">mitre</SvgParameter>\r\n",
+           prev);
+        sqlite3_free(prev);
+        prev = xml;
+        break;
+      case RL2_PEN_JOIN_BEVEL:
+        xml =
+          sqlite3_mprintf
+          ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">bevel</SvgParameter>\r\n",
+           prev);
+        sqlite3_free(prev);
+        prev = xml;
+        break;
+      default:
+        xml =
+          sqlite3_mprintf
+          ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">round</SvgParameter>\r\n",
+           prev);
+        sqlite3_free(prev);
+        prev = xml;
+        break;
+    };
+  switch (Stroke1LineCap)
+    {
+      case RL2_PEN_CAP_BUTT:
+        xml =
+          sqlite3_mprintf
+          ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">butt</SvgParameter>\r\n",
+           prev);
+        sqlite3_free(prev);
+        prev = xml;
+        break;
+      case RL2_PEN_CAP_SQUARE:
+        xml =
+          sqlite3_mprintf
+          ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">square</SvgParameter>\r\n",
+           prev);
+        sqlite3_free(prev);
+        prev = xml;
+        break;
+      default:
+        xml =
+          sqlite3_mprintf
+          ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">round</SvgParameter>\r\n",
+           prev);
+        sqlite3_free(prev);
+        prev = xml;
+        break;
+    };
+  if (Stroke1DashCount > 0 && Stroke1DashArray != NULL)
+    {
+      wxString dash;
+      NormalizedDashArray(dash, 0, ' ');
+      str = new char[strlen(dash.ToUTF8()) + 1];
+      strcpy(str, dash.ToUTF8());
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<SvgParameter name=\"stroke-dasharray\">%s</SvgParameter>\r\n",
+         prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      if (Stroke1DashOffset != 0.0)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"stroke-dashoffset\">%1.2f</SvgParameter>\r\n",
+             prev, Stroke1DashOffset);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+    }
+  xml = sqlite3_mprintf("%s\t\t\t</Stroke>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (PerpendicularOffset1 != 0.0)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t<PerpendicularOffset>%1.2f</PerpendicularOffset>\r\n", prev,
+         PerpendicularOffset1);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t</LineSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (EnableStroke2 == true)
+    {
+      // Stroke #2
+      switch (Uom)
+        {
+          case GUI_UOM_METRE:
+            cstr = "http://www.opengeospatial.org/se/units/metre";
+            break;
+          case GUI_UOM_INCH:
+            cstr = "http://www.opengeospatial.org/se/units/inch";
+            break;
+          default:
+            cstr = "http://www.opengeospatial.org/se/units/pixel";
+            break;
+        };
+      xml =
+        sqlite3_mprintf("%s\t\t<LineSymbolizer uom=\"%s\">\r\n", prev, cstr);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t\t<Stroke>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (HasGraphic2 == true)
+        {
+          // using an External Graphic
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<GraphicStroke>\r\n\t\t\t\t\t<Graphic>\r\n\t\t\t\t\t\t<ExternalGraphic>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Stroke2XLinkHref.ToUTF8()) + 1];
+          strcpy(str, Stroke2XLinkHref.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\" />\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Stroke2MimeType.ToUTF8()) + 1];
+          strcpy(str, Stroke2MimeType.ToUTF8());
+          xml =
+            sqlite3_mprintf("%s\t\t\t\t\t\t\t<Format>%s</Format>\r\n", prev,
+                            str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          if (EnableStroke2Replacement == true)
+            {
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t<ColorReplacement>\r\n\t\t\t\t\t\t\t\t<Recode fallbackValue=\"#000000\">\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t\t<LookupValue>ExternalGraphic</LookupValue>\r\n\t\t\t\t\t\t\t\t\t<MapItem>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              str = new char[strlen(Stroke2ColorReplacement.ToUTF8()) + 1];
+              strcpy(str, Stroke2ColorReplacement.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t\t\t<Data>1</Data>\r\n\t\t\t\t\t\t\t\t\t\t<Value>%s</Value>\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t\t</MapItem>\r\n\t\t\t\t\t\t\t\t</Recode>\r\n\t\t\t\t\t\t\t</ColorReplacement>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+            }
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t</ExternalGraphic>\r\n\t\t\t\t\t</Graphic>\r\n\t\t\t\t</GraphicStroke>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+      } else
+        {
+          // using a Solid Color
+          str = new char[strlen(Stroke2Color.ToUTF8()) + 1];
+          strcpy(str, Stroke2Color.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"stroke\">%s</SvgParameter>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<SvgParameter name=\"stroke-opacity\">%1.2f</SvgParameter>\r\n",
+         prev, Stroke2Opacity);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<SvgParameter name=\"stroke-width\">%1.2f</SvgParameter>\r\n",
+         prev, Stroke2Width);
+      sqlite3_free(prev);
+      prev = xml;
+      switch (Stroke2LineJoin)
+        {
+          case RL2_PEN_JOIN_MITER:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">mitre</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          case RL2_PEN_JOIN_BEVEL:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">bevel</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          default:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">round</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+        };
+      switch (Stroke2LineCap)
+        {
+          case RL2_PEN_CAP_BUTT:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">butt</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          case RL2_PEN_CAP_SQUARE:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">square</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          default:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">round</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+        };
+      if (Stroke2DashCount > 0 && Stroke2DashArray != NULL)
+        {
+          wxString dash;
+          NormalizedDashArray(dash, 1, ' ');
+          str = new char[strlen(dash.ToUTF8()) + 1];
+          strcpy(str, dash.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"stroke-dasharray\">%s</SvgParameter>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          if (Stroke2DashOffset != 0.0)
+            {
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t<SvgParameter name=\"stroke-dashoffset\">%1.2f</SvgParameter>\r\n",
+                 prev, Stroke2DashOffset);
+              sqlite3_free(prev);
+              prev = xml;
+            }
+        }
+      xml = sqlite3_mprintf("%s\t\t\t</Stroke>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (PerpendicularOffset2 != 0.0)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t<PerpendicularOffset>%1.2f</PerpendicularOffset>\r\n",
+             prev, PerpendicularOffset2);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t</LineSymbolizer>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (EnableStroke3 == true)
+    {
+      // Stroke #3
+      switch (Uom)
+        {
+          case GUI_UOM_METRE:
+            cstr = "http://www.opengeospatial.org/se/units/metre";
+            break;
+          case GUI_UOM_INCH:
+            cstr = "http://www.opengeospatial.org/se/units/inch";
+            break;
+          default:
+            cstr = "http://www.opengeospatial.org/se/units/pixel";
+            break;
+        };
+      xml =
+        sqlite3_mprintf("%s\t\t<LineSymbolizer uom=\"%s\">\r\n", prev, cstr);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t\t<Stroke>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (HasGraphic3 == true)
+        {
+          // using an External Graphic
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<GraphicStroke>\r\n\t\t\t\t\t<Graphic>\r\n\t\t\t\t\t\t<ExternalGraphic>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Stroke3XLinkHref.ToUTF8()) + 1];
+          strcpy(str, Stroke3XLinkHref.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\" />\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Stroke3MimeType.ToUTF8()) + 1];
+          strcpy(str, Stroke3MimeType.ToUTF8());
+          xml =
+            sqlite3_mprintf("%s\t\t\t\t\t\t\t<Format>%s</Format>\r\n", prev,
+                            str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          if (EnableStroke3Replacement == true)
+            {
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t<ColorReplacement>\r\n\t\t\t\t\t\t\t\t<Recode fallbackValue=\"#000000\">\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t\t<LookupValue>ExternalGraphic</LookupValue>\r\n\t\t\t\t\t\t\t\t\t<MapItem>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              str = new char[strlen(Stroke3ColorReplacement.ToUTF8()) + 1];
+              strcpy(str, Stroke3ColorReplacement.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t\t\t<Data>1</Data>\r\n\t\t\t\t\t\t\t\t\t\t<Value>%s</Value>\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t\t</MapItem>\r\n\t\t\t\t\t\t\t\t</Recode>\r\n\t\t\t\t\t\t\t</ColorReplacement>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+            }
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t</ExternalGraphic>\r\n\t\t\t\t\t</Graphic>\r\n\t\t\t\t</GraphicStroke>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+      } else
+        {
+          // using a Solid Color
+          str = new char[strlen(Stroke3Color.ToUTF8()) + 1];
+          strcpy(str, Stroke3Color.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"stroke\">%s</SvgParameter>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<SvgParameter name=\"stroke-opacity\">%1.2f</SvgParameter>\r\n",
+         prev, Stroke3Opacity);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<SvgParameter name=\"stroke-width\">%1.2f</SvgParameter>\r\n",
+         prev, Stroke3Width);
+      sqlite3_free(prev);
+      prev = xml;
+      switch (Stroke3LineJoin)
+        {
+          case RL2_PEN_JOIN_MITER:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">mitre</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          case RL2_PEN_JOIN_BEVEL:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">bevel</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          default:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">round</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+        };
+      switch (Stroke3LineCap)
+        {
+          case RL2_PEN_CAP_BUTT:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">butt</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          case RL2_PEN_CAP_SQUARE:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">square</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          default:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">round</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+        };
+      if (Stroke3DashCount > 0 && Stroke3DashArray != NULL)
+        {
+          wxString dash;
+          NormalizedDashArray(dash, 0, ' ');
+          str = new char[strlen(dash.ToUTF8()) + 1];
+          strcpy(str, dash.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"stroke-dasharray\">%s</SvgParameter>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          if (Stroke3DashOffset != 0.0)
+            {
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t<SvgParameter name=\"stroke-dashoffset\">%1.2f</SvgParameter>\r\n",
+                 prev, Stroke1DashOffset);
+              sqlite3_free(prev);
+              prev = xml;
+            }
+        }
+      xml = sqlite3_mprintf("%s\t\t\t</Stroke>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (PerpendicularOffset3 != 0.0)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t<PerpendicularOffset>%1.2f</PerpendicularOffset>\r\n",
+             prev, PerpendicularOffset3);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t</LineSymbolizer>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t</Rule>\r\n</FeatureTypeStyle>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+char *SimpleLineSymbolizerDialog::DoCreateSymbolizerXML()
+{
+//
+// creating the SLD/SE (XML) code - LineSymbolizer
+//
+  char *str;
+  const char *cstr;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<LineSymbolizer version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/Symbolizer.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  switch (Uom)
+    {
+      case GUI_UOM_METRE:
+        cstr = "http://www.opengeospatial.org/se/units/metre";
+        break;
+      case GUI_UOM_INCH:
+        cstr = "http://www.opengeospatial.org/se/units/inch";
+        break;
+      default:
+        cstr = "http://www.opengeospatial.org/se/units/pixel";
+        break;
+    };
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" uom=\"%s\">\r\n",
+     prev, cstr);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Stroke>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (HasGraphic1 == true)
+    {
+      // using an External Graphic
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<GraphicStroke>\r\n\t\t\t<Graphic>\r\n\t\t\t\t<ExternalGraphic>\r\n",
+         prev);
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(Stroke1XLinkHref.ToUTF8()) + 1];
+      strcpy(str, Stroke1XLinkHref.ToUTF8());
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t\t<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\" />\r\n",
+         prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(Stroke1MimeType.ToUTF8()) + 1];
+      strcpy(str, Stroke1MimeType.ToUTF8());
+      xml = sqlite3_mprintf("%s\t\t\t\t\t<Format>%s</Format>\r\n", prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      if (EnableStroke1Replacement == true)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t<ColorReplacement>\r\n\t\t\t\t\t\t<Recode fallbackValue=\"#000000\">\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t<LookupValue>ExternalGraphic</LookupValue>\r\n\t\t\t\t\t\t\t<MapItem>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Stroke1ColorReplacement.ToUTF8()) + 1];
+          strcpy(str, Stroke1ColorReplacement.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t\t<Data>1</Data>\r\n\t\t\t\t\t\t\t\t<Value>%s</Value>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t</MapItem>\r\n\t\t\t\t\t\t</Recode>\r\n\t\t\t\t\t</ColorReplacement>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t</ExternalGraphic>\r\n\t\t\t</Graphic>\r\n\t\t</GraphicStroke>\r\n",
+         prev);
+      sqlite3_free(prev);
+      prev = xml;
+  } else
+    {
+      // using a Solid Color
+      str = new char[strlen(Stroke1Color.ToUTF8()) + 1];
+      strcpy(str, Stroke1Color.ToUTF8());
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<SvgParameter name=\"stroke\">%s</SvgParameter>\r\n", prev,
+         str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t<SvgParameter name=\"stroke-opacity\">%1.2f</SvgParameter>\r\n",
+     prev, Stroke1Opacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t<SvgParameter name=\"stroke-width\">%1.2f</SvgParameter>\r\n", prev,
+     Stroke1Width);
+  sqlite3_free(prev);
+  prev = xml;
+  switch (Stroke1LineJoin)
+    {
+      case RL2_PEN_JOIN_MITER:
+        xml =
+          sqlite3_mprintf
+          ("%s\t\t<SvgParameter name=\"stroke-linejoin\">mitre</SvgParameter>\r\n",
+           prev);
+        sqlite3_free(prev);
+        prev = xml;
+        break;
+      case RL2_PEN_JOIN_BEVEL:
+        xml =
+          sqlite3_mprintf
+          ("%s\t\t<SvgParameter name=\"stroke-linejoin\">bevel</SvgParameter>\r\n",
+           prev);
+        sqlite3_free(prev);
+        prev = xml;
+        break;
+      default:
+        xml =
+          sqlite3_mprintf
+          ("%s\t\t<SvgParameter name=\"stroke-linejoin\">round</SvgParameter>\r\n",
+           prev);
+        sqlite3_free(prev);
+        prev = xml;
+        break;
+    };
+  switch (Stroke1LineCap)
+    {
+      case RL2_PEN_CAP_BUTT:
+        xml =
+          sqlite3_mprintf
+          ("%s\t\t<SvgParameter name=\"stroke-linecap\">butt</SvgParameter>\r\n",
+           prev);
+        sqlite3_free(prev);
+        prev = xml;
+        break;
+      case RL2_PEN_CAP_SQUARE:
+        xml =
+          sqlite3_mprintf
+          ("%s\t\t<SvgParameter name=\"stroke-linecap\">square</SvgParameter>\r\n",
+           prev);
+        sqlite3_free(prev);
+        prev = xml;
+        break;
+      default:
+        xml =
+          sqlite3_mprintf
+          ("%s\t\t<SvgParameter name=\"stroke-linecap\">round</SvgParameter>\r\n",
+           prev);
+        sqlite3_free(prev);
+        prev = xml;
+        break;
+    };
+  if (Stroke1DashCount > 0 && Stroke1DashArray != NULL)
+    {
+      wxString dash;
+      NormalizedDashArray(dash, 0, ' ');
+      str = new char[strlen(dash.ToUTF8()) + 1];
+      strcpy(str, dash.ToUTF8());
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<SvgParameter name=\"stroke-dasharray\">%s</SvgParameter>\r\n",
+         prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      if (Stroke1DashOffset != 0.0)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t<SvgParameter name=\"stroke-dashoffset\">%1.2f</SvgParameter>\r\n",
+             prev, Stroke1DashOffset);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+    }
+  xml = sqlite3_mprintf("%s\t</Stroke>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (PerpendicularOffset1 != 0.0)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t<PerpendicularOffset>%1.2f</PerpendicularOffset>\r\n", prev,
+         PerpendicularOffset1);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s</LineSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+void SimpleLineSymbolizerDialog::OnInsert(wxCommandEvent & WXUNUSED(event))
+{
+//
+// inserting the VectorSymbolizer into the DBMS
+//
+  switch (GetBookCtrl()->GetSelection())
+    {
+      case 0:
+        RetrieveMainPage();
+        break;
+      case 1:
+        RetrieveStroke1Page();
+        break;
+      case 2:
+        RetrieveStroke2Page();
+        break;
+      case 3:
+        RetrieveStroke3Page();
+        break;
+      case 4:
+        RetrievePreviewPage();
+        break;
+    };
+  if (FinalValidityCheck() == false)
+    {
+      GetBookCtrl()->ChangeSelection(0);
+      return;
+    }
+  char *xml;
+  if (MinScale == true || MaxScale == true || EnableStroke2 == true
+      || EnableStroke3 == true)
+    xml = DoCreateFeatureTypeXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  if (MainFrame->DoInsertVectorSymbolizer(xml) == true)
+    wxMessageBox(wxT
+                 ("SLD/SE VectorSymbolizer successfully registered into the DBMS"),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  wxDialog::EndModal(wxID_OK);
+}
+
+void SimpleLineSymbolizerDialog::OnExport(wxCommandEvent & WXUNUSED(event))
+{
+//
+// exporting the VectorSymbolizer as an external file
+//
+  int ret;
+  wxString path;
+  wxString lastDir;
+  switch (GetBookCtrl()->GetSelection())
+    {
+      case 0:
+        RetrieveMainPage();
+        break;
+      case 1:
+        RetrieveStroke1Page();
+        break;
+      case 2:
+        RetrieveStroke2Page();
+        break;
+      case 3:
+        RetrieveStroke3Page();
+        break;
+      case 4:
+        RetrievePreviewPage();
+        break;
+    };
+  if (FinalValidityCheck() == false)
+    {
+      GetBookCtrl()->ChangeSelection(0);
+      return;
+    }
+  wxFileDialog fileDialog(this,
+                          wxT("Exporting an SLD/SE LineSymbolizer to a file"),
+                          wxT(""), Name + wxT(".xml"),
+                          wxT("XML Document|*.xml|All files (*.*)|*.*"),
+                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      wxFileName file(fileDialog.GetPath());
+      path = file.GetPath();
+      path += file.GetPathSeparator();
+      path += file.GetName();
+      lastDir = file.GetPath();
+      path = fileDialog.GetPath();
+      FILE *out = fopen(path.ToUTF8(), "wb");
+      if (out == NULL)
+        wxMessageBox(wxT("ERROR: unable to create:\n\n\"") + path + wxT("\""),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else
+        {
+          char *xml;
+          if (MinScale == true || MaxScale == true || EnableStroke2 == true
+              || EnableStroke3 == true)
+            xml = DoCreateFeatureTypeXML();
+          else
+            xml = DoCreateSymbolizerXML();
+          fwrite(xml, 1, strlen(xml), out);
+          sqlite3_free(xml);
+          fclose(out);
+          wxMessageBox(wxT
+                       ("SLD/SE LineSymbolizer successfully saved into:\n\n\"")
+                       + path + wxT("\""), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+void SimpleLineSymbolizerDialog::OnCopy(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Copying the VectorSymbolizer into the Clipboard 
+//
+  switch (GetBookCtrl()->GetSelection())
+    {
+      case 0:
+        RetrieveMainPage();
+        break;
+      case 1:
+        RetrieveStroke1Page();
+        break;
+      case 2:
+        RetrieveStroke2Page();
+        break;
+      case 3:
+        RetrieveStroke3Page();
+        break;
+      case 4:
+        RetrievePreviewPage();
+        break;
+    };
+  if (FinalValidityCheck() == false)
+    {
+      GetBookCtrl()->ChangeSelection(0);
+      return;
+    }
+  char *xml;
+  if (MinScale == true || MaxScale == true || EnableStroke2 == true
+      || EnableStroke3 == true)
+    xml = DoCreateFeatureTypeXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  wxString XMLstring = wxString::FromUTF8(xml);
+  if (wxTheClipboard->Open())
+    {
+      wxTheClipboard->SetData(new wxTextDataObject(XMLstring));
+      wxTheClipboard->Close();
+    }
+}
+
+void SimpleLineSymbolizerDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+bool MyFrame::ValidateVectorStyle(void **blob, int *blob_size, const char *xml)
+{
+//
+// attempting to parse and validate a Vector Style
+//
+  int ret;
+  sqlite3_stmt *stmt;
+  void *xblob = NULL;
+  int xblob_size;
+  int valid = 0;
+
+// Schema validation
+  const char *sql = "SELECT XB_Create(?, 1, 1)";
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_blob(stmt, 1, xml, strlen(xml), SQLITE_STATIC);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_BLOB)
+            {
+              const void *xxblob = sqlite3_column_blob(stmt, 0);
+              xblob_size = sqlite3_column_bytes(stmt, 0);
+              xblob = malloc(xblob_size);
+              memcpy(xblob, xxblob, xblob_size);
+            }
+      } else
+        {
+          sqlite3_finalize(stmt);
+          return false;
+        }
+    }
+  sqlite3_finalize(stmt);
+  if (xblob == NULL)
+    return false;
+
+// Checking if really is a Vector Style
+  stmt = NULL;
+  sql = "SELECT XB_IsSldSEVectorStyle(?)";
+  ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    goto invalid;
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_blob(stmt, 1, xblob, xblob_size, SQLITE_STATIC);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
+            valid = sqlite3_column_int(stmt, 0);
+      } else
+        goto invalid;
+    }
+  sqlite3_finalize(stmt);
+  stmt = NULL;
+  if (!valid)
+    goto invalid;
+  *blob = xblob;
+  *blob_size = xblob_size;
+  return true;
+
+invalid:
+  if (stmt != NULL)
+    sqlite3_finalize(stmt);
+  free(xblob);
+  *blob = NULL;
+  *blob_size = 0;
+  return false;
+}
+
+bool MyFrame::DoInsertVectorSymbolizer(char *xml)
+{
+//
+// attempting to register a VectorSymbolizer
+//
+  void *blob = NULL;
+  int blob_size;
+  ::wxBeginBusyCursor();
+  if (ValidateVectorStyle(&blob, &blob_size, xml) != true)
+    {
+      ::wxEndBusyCursor();
+      wxMessageBox(wxT("Error: not a valid SLD/SE VectorSymbolizer"),
+                   wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      sqlite3_free(xml);
+      return false;
+    }
+  ::wxEndBusyCursor();
+  sqlite3_free(xml);
+
+  sqlite3_stmt *stmt = NULL;
+  const char *sql = "SELECT SE_RegisterVectorStyle(?)";
+  int ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql),
+                               &stmt, NULL);
+  if (ret != SQLITE_OK)
+    return false;
+
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  sqlite3_bind_blob(stmt, 1, blob, blob_size, free);
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+    ;
+  else
+    {
+      sqlite3_finalize(stmt);
+      return false;
+    }
+  sqlite3_finalize(stmt);
+  return true;
+}
+
+
+ExternalGraphic::ExternalGraphic(wxString & xlink_href, wxString & title,
+                                 wxString & abstract, wxString & mime_type,
+                                 const void *blob, int blob_sz)
+{
+// ctor
+  XLinkHref = xlink_href;
+  Title = title;
+  Abstract = abstract;
+  MimeType = mime_type;
+  if (DoBuildGraphic(mime_type, blob, blob_sz) != true)
+    DoBuildDefaultGraphic();
+  Next = NULL;
+}
+
+bool ExternalGraphic::DoBuildGraphic(wxString & mime_type, const void *blob,
+                                     int blob_sz)
+{
+// attempting to build an Image from BLOB
+  rl2RasterPtr raster = NULL;
+  if (mime_type.CmpNoCase(wxT("image/png")) == 0)
+    raster = rl2_raster_from_png((const unsigned char *) blob, blob_sz, 1);
+  if (mime_type.CmpNoCase(wxT("image/gif")) == 0)
+    raster = rl2_raster_from_gif((const unsigned char *) blob, blob_sz);
+  if (mime_type.CmpNoCase(wxT("image/jpeg")) == 0)
+    raster = rl2_raster_from_jpeg((const unsigned char *) blob, blob_sz);
+  if (mime_type.CmpNoCase(wxT("image/svg+xml")) == 0)
+    {
+      // preparing an SVG icon
+      char *svg = gaiaXmlTextFromBlob((const unsigned char *) blob, blob_sz, 0);
+      int svg_sz = strlen(svg);
+      rl2SvgPtr svg_handle =
+        rl2_create_svg((const unsigned char *) svg, svg_sz);
+      if (svg_handle != NULL)
+        {
+          double SvgWidth;
+          double SvgHeight;
+          if (rl2_get_svg_size(svg_handle, &SvgWidth, &SvgHeight) == RL2_OK)
+            {
+              double w = SvgWidth;
+              double h = SvgHeight;
+              if (SvgWidth > 48.0 || SvgHeight > 24.0)
+                {
+                  while (w > 48.0 || h > 24.0)
+                    {
+                      // rescaling
+                      w *= 0.999;
+                      h *= 0.999;
+                    }
+              } else
+                {
+                  while (w < 47.0 && h < 23.0)
+                    {
+                      // rescaling
+                      w *= 1.001;
+                      h *= 1.001;
+                    }
+                }
+              double sz = w;
+              if (h > sz)
+                sz = h;
+              raster = rl2_raster_from_svg(svg_handle, sz);
+            }
+          rl2_destroy_svg(svg_handle);
+        }
+      free(svg);
+    }
+  if (raster == NULL)
+    return false;
+
+// ok, building a wxImage
+  unsigned int width;
+  unsigned int height;
+  unsigned char *rgbaArray = NULL;
+  int rgbaSize;
+  if (rl2_get_raster_size(raster, &width, &height) == RL2_OK)
+    {
+      if (rl2_raster_data_to_RGBA(raster, &rgbaArray, &rgbaSize) != RL2_OK)
+        rgbaArray = NULL;
+    }
+  rl2_destroy_raster(raster);
+  if (rgbaArray == NULL)
+    return false;
+  // creating the Image from RGB array
+  unsigned int x;
+  unsigned int y;
+  wxImage img = wxImage(width, height);
+  unsigned char *p = rgbaArray;
+  img.SetAlpha();
+  for (y = 0; y < height; y++)
+    {
+      for (x = 0; x < width; x++)
+        {
+          unsigned char r = *p++;
+          unsigned char g = *p++;
+          unsigned char b = *p++;
+          unsigned char alpha = *p++;
+          img.SetRGB(x, y, r, g, b);
+          img.SetAlpha(x, y, alpha);
+        }
+    }
+  free(rgbaArray);
+
+// normalized rescaling
+  int norm_width = width;
+  int norm_height = height;
+  double incr;
+  double ww = width;
+  double hh = height;
+  if (width > 48 || height > 24)
+    {
+      incr = 0.999;
+      while (1)
+        {
+          ww *= incr;
+          hh *= incr;
+          if (ww > 47.0 || hh > 23.0)
+            {
+              norm_width = ww;
+              norm_height = hh;
+          } else
+            break;
+        }
+  } else
+    {
+      incr = 1.001;
+      while (1)
+        {
+          ww *= incr;
+          hh *= incr;
+          if (ww <= 48.0 && hh <= 24.0)
+            {
+              norm_width = ww;
+              norm_height = hh;
+          } else
+            break;
+        }
+    }
+  Graphic = img.Rescale(norm_width, norm_height);
+
+
+  return true;
+}
+
+void ExternalGraphic::DoBuildDefaultGraphic()
+{
+// building a default gray image
+  Graphic = wxImage(48, 24);
+  for (int y = 0; y < 24; y++)
+    {
+      for (int x = 0; x < 48; x++)
+        Graphic.SetRGB(x, y, 128, 128, 128);
+    }
+}
+
+ExternalGraphicList::~ExternalGraphicList()
+{
+// dtor
+  ExternalGraphic *pE;
+  ExternalGraphic *pEn;
+  pE = First;
+  while (pE != NULL)
+    {
+      pEn = pE->GetNext();
+      delete pE;
+      pE = pEn;
+    }
+}
+
+void ExternalGraphicList::Add(wxString & xlink_href, wxString & title,
+                              wxString & abstract, wxString & mime_type,
+                              const void *blob, int blob_sz)
+{
+// inserting a new External Graphic into the list
+  ExternalGraphic *pE =
+    new ExternalGraphic(xlink_href, title, abstract, mime_type, blob, blob_sz);
+  if (First == NULL)
+    First = pE;
+  if (Last != NULL)
+    Last->SetNext(pE);
+  Last = pE;
+}
+
+void ExternalGraphicList::FindByIndex(int idx, wxString & xlink_href,
+                                      wxString & mime_type)
+{
+// searching an entry by its position
+  ExternalGraphic *pE;
+  int count = 0;
+  pE = First;
+  while (pE != NULL)
+    {
+      if (idx == count)
+        {
+          xlink_href = pE->GetXLinkHref();
+          mime_type = pE->GetMimeType();
+          return;
+        }
+      count++;
+      pE = pE->GetNext();
+    }
+  xlink_href = wxT("");
+}
+
+int ExternalGraphicList::FindByXLinkHref(wxString & xlink_href)
+{
+// searching an entry by XLinkHref value 
+  ExternalGraphic *pE;
+  int count = 0;
+  pE = First;
+  while (pE != NULL)
+    {
+      if (xlink_href.CmpNoCase(pE->GetXLinkHref()) == 0)
+        return count;
+      count++;
+      pE = pE->GetNext();
+    }
+  return -1;
+}
+
+ExternalGraphicList *MyFrame::FindExternalGraphic(bool no_svg)
+{
+// will retrieve all registered External Graphics
+  ExternalGraphicList *list = new ExternalGraphicList();
+  sqlite3_stmt *stmt = NULL;
+  const char *sql;
+
+  sql =
+    "SELECT xlink_href, title, abstract, GetMimeType(resource), resource "
+    "FROM SE_external_graphics";
+  int ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    {
+      delete list;
+      return NULL;
+    }
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          wxString xlink_href;
+          wxString title;
+          wxString abstract;
+          wxString mime_type;
+          const void *blob = NULL;
+          int blob_sz = 0;
+          const char *str = (const char *) sqlite3_column_text(stmt, 0);
+          xlink_href = wxString::FromUTF8(str);
+          str = (const char *) sqlite3_column_text(stmt, 1);
+          title = wxString::FromUTF8(str);
+          str = (const char *) sqlite3_column_text(stmt, 2);
+          abstract = wxString::FromUTF8(str);
+          str = (const char *) sqlite3_column_text(stmt, 3);
+          if (no_svg == true && strcasecmp(str, "image/svg+xml") == 0)
+            continue;
+          mime_type = wxString::FromUTF8(str);
+          if (sqlite3_column_type(stmt, 4) == SQLITE_BLOB)
+            {
+              blob = sqlite3_column_blob(stmt, 4);
+              blob_sz = sqlite3_column_bytes(stmt, 4);
+            }
+          list->Add(xlink_href, title, abstract, mime_type, blob, blob_sz);
+      } else
+        {
+          sqlite3_finalize(stmt);
+          delete list;
+          return NULL;
+        }
+    }
+  sqlite3_finalize(stmt);
+  return list;
+}
+
+void MyGraphicCellRenderer::Draw(wxGrid & grid, wxGridCellAttr & attr,
+                                 wxDC & dc, const wxRect & rect, int row,
+                                 int col, bool isSelected)
+{
+// drawing a Graphic cell
+  wxBitmap bmp = wxBitmap(*Graphic);
+  wxColour color = attr.GetBackgroundColour();
+  if (grid.IsEnabled() == false)
+    {
+      color = wxSystemSettings::GetColour(wxSYS_COLOUR_MENU);
+      wxImage img = Graphic->ConvertToGreyscale();
+      bmp = wxBitmap(img);
+    }
+  dc.SetBrush(wxBrush(color));
+  dc.SetPen(*wxTRANSPARENT_PEN);
+  dc.DrawRectangle(rect);
+  int x = (rect.GetWidth() - bmp.GetWidth()) / 2;
+  int y = (rect.GetHeight() - bmp.GetHeight()) / 2;
+  dc.DrawBitmap(bmp, rect.x + x, rect.y + y, true);
+}
+
+SymbolizerPreview::SymbolizerPreview(wxPropertySheetDialog * parent,
+                                     wxWindow * panel, wxWindowID id,
+                                     const wxBitmap & bmp,
+                                     const wxSize & size):wxStaticBitmap(panel,
+                                                                         id,
+                                                                         bmp,
+                                                                         wxDefaultPosition,
+                                                                         size)
+{
+  Parent = parent;
+}
+
+SimplePolygonSymbolizerDialog::SimplePolygonSymbolizerDialog()
+{
+// ctor
+  Stroke1DashArray = NULL;
+  Stroke2DashArray = NULL;
+  List = NULL;
+}
+
+SimplePolygonSymbolizerDialog::~SimplePolygonSymbolizerDialog()
+{
+// dtor
+  if (Stroke1DashArray != NULL)
+    delete[]Stroke1DashArray;
+  if (Stroke2DashArray != NULL)
+    delete[]Stroke2DashArray;
+  if (List)
+    delete List;
+}
+
+bool SimplePolygonSymbolizerDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Uom = GUI_UOM_PIXEL;
+  MinScale = false;
+  MaxScale = false;
+  DisplacementX1 = 0.0;
+  DisplacementY1 = 0.0;
+  PerpendicularOffset1 = 0.0;
+  EnableStroke1 = true;
+  HasGraphicStroke1 = false;
+  Stroke1Opacity = 1.0;
+  Stroke1Color = wxT("#000000");
+  EnableStroke1Replacement = false;
+  Stroke1ColorReplacement = wxT("#000000");
+  Stroke1Width = 1.0;
+  Stroke1LineJoin = RL2_PEN_JOIN_ROUND;
+  Stroke1LineCap = RL2_PEN_CAP_ROUND;
+  Stroke1DashCount = 0;
+  Stroke1DashOffset = 0.0;
+  EnableFill1 = true;
+  HasGraphicFill1 = false;
+  Fill1Opacity = 1.0;
+  Fill1Color = wxT("#808080");
+  EnableFill1Replacement = false;
+  Fill1ColorReplacement = wxT("#000000");
+  EnablePolygon2 = false;
+  EnableStroke2 = false;
+  DisplacementX2 = 0.0;
+  DisplacementY2 = 0.0;
+  PerpendicularOffset2 = 0.0;
+  Stroke2Opacity = 1.0;
+  HasGraphicStroke2 = false;
+  Stroke2Color = wxT("#000000");
+  EnableStroke2Replacement = false;
+  Stroke2ColorReplacement = wxT("#000000");
+  Stroke2Width = 1.0;
+  Stroke2LineJoin = RL2_PEN_JOIN_ROUND;
+  Stroke2LineCap = RL2_PEN_CAP_ROUND;
+  Stroke2DashCount = 0;
+  Stroke2DashOffset = 0.0;
+  EnableFill2 = false;
+  HasGraphicFill2 = false;
+  Fill2Opacity = 1.0;
+  Fill2Color = wxT("#808080");
+  EnableFill2Replacement = false;
+  Fill2ColorReplacement = wxT("#000000");
+  PreviewBackground = GUI_PREVIEW_BACKGROUND_CHECKED;
+  List = MainFrame->FindExternalGraphic(true);
+
+  if (wxPropertySheetDialog::Create
+      (parent, wxID_ANY, wxT("Simple Polygon Symbolizer")) == false)
+    return false;
+  wxBookCtrlBase *book = GetBookCtrl();
+// creates individual panels
+  wxPanel *mainPage = CreateMainPage(book);
+  book->AddPage(mainPage, wxT("General"), true);
+  wxPanel *fill1Page = CreateFill1Page(book);
+  book->AddPage(fill1Page, wxT("Polygon #1 Fill"), false);
+  wxPanel *stroke1Page = CreateStroke1Page(book);
+  book->AddPage(stroke1Page, wxT("Polygon #1 Stroke"), false);
+  wxPanel *fill2Page = CreateFill2Page(book);
+  book->AddPage(fill2Page, wxT("Polygon #2 Fill"), false);
+  wxPanel *stroke2Page = CreateStroke2Page(book);
+  book->AddPage(stroke2Page, wxT("Polygon #2 Stroke"), false);
+  wxPanel *previewPage = CreatePreviewPage(book);
+  book->AddPage(previewPage, wxT("Preview"), false);
+
+  CreateButtons();
+  LayoutDialog();
+// appends event handler for TAB/PAGE changing
+  Connect(wxID_ANY, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnPageChanging);
+  Connect(wxID_ANY, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnPageChanged);
+// appends event handler for buttons
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimplePolygonSymbolizerDialog::OnQuit);
+  Connect(ID_SYMBOLIZER_INSERT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimplePolygonSymbolizerDialog::OnInsert);
+  Connect(ID_SYMBOLIZER_EXPORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimplePolygonSymbolizerDialog::OnExport);
+  Connect(ID_SYMBOLIZER_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimplePolygonSymbolizerDialog::OnCopy);
+// centers the dialog window
+  Centre();
+  UpdateMainPage();
+  return true;
+}
+
+wxPanel *SimplePolygonSymbolizerDialog::CreateMainPage(wxWindow * parent)
+{
+//
+// creating the MAIN page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_MAIN);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+// first row: the PolygonSymbolizer Name
+  wxBoxSizer *nameSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(nameSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *nameLabel = new wxStaticText(panel, wxID_STATIC, wxT("&Name:"));
+  nameSizer->Add(nameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *nameCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_NAME, wxT(""),
+                                        wxDefaultPosition, wxSize(600, 22));
+  nameSizer->Add(nameCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the PolygonSymbolizer Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the PolygonSymbolizer Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_ABSTRACT, wxT(""),
+                   wxDefaultPosition, wxSize(600, 60),
+                   wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: UOM and Visibility Range
+  boxSizer->AddSpacer(50);
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// fourth row A: Unit Of Measure - UOM
+  wxString uom[3];
+  uom[0] = wxT("&Pixel");
+  uom[1] = wxT("&Metre");
+  uom[2] = wxT("&Inch");
+  wxRadioBox *uomBox = new wxRadioBox(panel, ID_SYMBOLIZER_UOM,
+                                      wxT("&Unit Of Measure"),
+                                      wxDefaultPosition,
+                                      wxDefaultSize, 3,
+                                      uom, 1,
+                                      wxRA_SPECIFY_ROWS);
+  miscSizer->Add(uomBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  uomBox->SetSelection(0);
+// fourth row B: optional Visibility Range
+  miscSizer->AddSpacer(50);
+  wxBoxSizer *visibilityBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(visibilityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *visibilityBox = new wxStaticBox(panel, wxID_STATIC,
+                                               wxT("Visibility Range"),
+                                               wxDefaultPosition,
+                                               wxDefaultSize);
+  wxBoxSizer *visibilitySizer =
+    new wxStaticBoxSizer(visibilityBox, wxHORIZONTAL);
+  visibilityBoxSizer->Add(visibilitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL,
+                          5);
+  wxString range[4];
+  range[0] = wxT("&None");
+  range[1] = wxT("&Min");
+  range[2] = wxT("&Max");
+  range[3] = wxT("&Both");
+  wxRadioBox *rangeBox = new wxRadioBox(panel, ID_SYMBOLIZER_MINMAX_SCALE,
+                                        wxT("&Range Type"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 4,
+                                        range, 2,
+                                        wxRA_SPECIFY_COLS);
+  visibilitySizer->Add(rangeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  rangeBox->SetSelection(0);
+  visibilitySizer->AddSpacer(20);
+  wxBoxSizer *scaleBoxSizer = new wxBoxSizer(wxVERTICAL);
+  visibilitySizer->Add(scaleBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *scaleMinSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMinSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *minScaleLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Min Scale:"));
+  scaleMinSizer->Add(minScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *minScaleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_MIN_SCALE, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  minScaleCtrl->Enable(false);
+  scaleMinSizer->Add(minScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *scaleMaxSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMaxSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *maxScaleLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Max Scale:"));
+  scaleMaxSizer->Add(maxScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *maxScaleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_MAX_SCALE, wxT("+Infinite"),
+                   wxDefaultPosition, wxSize(100, 22));
+  maxScaleCtrl->Enable(false);
+  scaleMaxSizer->Add(maxScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_UOM, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdUomChanged);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdScaleChanged);
+  return panel;
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdUomChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// UOM selection changed
+//
+  wxRadioBox *uomCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_UOM);
+  switch (uomCtrl->GetSelection())
+    {
+      case 1:
+        Uom = GUI_UOM_METRE;
+        break;
+      case 2:
+        Uom = GUI_UOM_INCH;
+        break;
+      default:
+        Uom = GUI_UOM_PIXEL;
+        break;
+    };
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdScaleChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Visibility Range selection changed
+//
+  wxRadioBox *scaleModeCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  switch (scaleModeCtrl->GetSelection())
+    {
+      case 0:
+        MinScale = false;
+        MaxScale = false;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 1:
+        MinScale = true;
+        MaxScale = false;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 2:
+        MinScale = false;
+        MaxScale = true;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+      case 3:
+        MinScale = true;
+        MaxScale = true;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+    };
+}
+
+wxPanel *SimplePolygonSymbolizerDialog::CreateFill1Page(wxWindow * parent)
+{
+//
+// creating the Polygon #1 Fill page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_FILL1);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+// first row: the Polygon #1 Displacement and Perpendicular Offset
+  wxBoxSizer *polygonBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(polygonBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *polygonBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("Polygon #1"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *polygonSizer = new wxStaticBoxSizer(polygonBox, wxHORIZONTAL);
+  polygonBoxSizer->Add(polygonSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// first row A: Displacement
+  wxBoxSizer *displacementBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  polygonSizer->Add(displacementBoxSizer, 0,
+                    wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *displacementBox = new wxStaticBox(panel, wxID_STATIC,
+                                                 wxT("Displacement"),
+                                                 wxDefaultPosition,
+                                                 wxDefaultSize);
+  wxBoxSizer *displacementSizer =
+    new wxStaticBoxSizer(displacementBox, wxVERTICAL);
+  displacementBoxSizer->Add(displacementSizer, 0,
+                            wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *displ1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  displacementSizer->Add(displ1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *displ1Label = new wxStaticText(panel, wxID_STATIC, wxT("X"));
+  displ1Sizer->Add(displ1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxTextCtrl *displacementXCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_POLYGON1_DISPLACEMENT_X, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  displ1Sizer->Add(displacementXCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxBoxSizer *displ2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  displacementSizer->Add(displ2Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *displ2Label = new wxStaticText(panel, wxID_STATIC, wxT("Y"));
+  displ2Sizer->Add(displ2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxTextCtrl *displacementYCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_POLYGON1_DISPLACEMENT_Y, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  displ2Sizer->Add(displacementYCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+// first row B: PerpendicularOffset
+  wxBoxSizer *perpendicularBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  polygonSizer->Add(perpendicularBoxSizer, 0,
+                    wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *perpendicularBox = new wxStaticBox(panel, wxID_STATIC,
+                                                  wxT("Perpendicular Offset"),
+                                                  wxDefaultPosition,
+                                                  wxDefaultSize);
+  wxBoxSizer *perpendicularSizer =
+    new wxStaticBoxSizer(perpendicularBox, wxVERTICAL);
+  perpendicularBoxSizer->Add(perpendicularSizer, 0,
+                             wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *perp1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  perpendicularSizer->Add(perp1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxTextCtrl *perpendicularCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_POLYGON1_PERPENDICULAR, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  perp1Sizer->Add(perpendicularCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxStaticText *perp1Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT
+                                              ("Positive: larger. / Negative: smaller."));
+  perp1Sizer->Add(perp1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxStaticText *perp2Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT
+                                              ("Drawing polygons smaller or larger than their actual geometry (Buffer)."));
+  perpendicularSizer->Add(perp2Label, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// second row: Fill#1 Opacity
+  wxBoxSizer *auxBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(auxBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *auxBox = new wxStaticBox(panel, wxID_STATIC,
+                                        wxT("Polygon #1 Fill"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize);
+  wxBoxSizer *auxSizer = new wxStaticBoxSizer(auxBox, wxVERTICAL);
+  auxBoxSizer->Add(auxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *enableSizer = new wxBoxSizer(wxHORIZONTAL);
+  auxSizer->Add(enableSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxCheckBox *enableCtrl = new wxCheckBox(panel, ID_SYMBOLIZER_FILL1_ENABLE,
+                                          wxT("Enable"),
+                                          wxDefaultPosition, wxDefaultSize);
+  enableCtrl->SetValue(true);
+  enableSizer->Add(enableCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *opacityBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  enableSizer->Add(opacityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *opacityBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("Opacity"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *opacitySizer = new wxStaticBoxSizer(opacityBox, wxVERTICAL);
+  opacityBoxSizer->Add(opacitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxSlider *opacityCtrl =
+    new wxSlider(panel, ID_SYMBOLIZER_FILL1_OPACITY, 100, 0, 100,
+                 wxDefaultPosition, wxSize(600, 45),
+                 wxSL_HORIZONTAL | wxSL_LABELS);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// third row: Fill color or Graphic
+  wxBoxSizer *fillSizer = new wxBoxSizer(wxHORIZONTAL);
+  auxSizer->Add(fillSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// third row A: Fill Type
+  wxBoxSizer *fill1Sizer = new wxBoxSizer(wxVERTICAL);
+  fillSizer->Add(fill1Sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxString type[2];
+  type[0] = wxT("&Color");
+  type[1] = wxT("&Graphic");
+  wxRadioBox *typeBox = new wxRadioBox(panel, ID_SYMBOLIZER_FILL1_TYPE,
+                                       wxT("&Fill Type"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 2,
+                                       type, 1,
+                                       wxRA_SPECIFY_ROWS);
+  fill1Sizer->Add(typeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  typeBox->SetSelection(0);
+// third row B: Fill Color
+  wxBoxSizer *colorBoxSizer = new wxBoxSizer(wxVERTICAL);
+  fill1Sizer->Add(colorBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *colorBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Fill Color"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *colorSizer = new wxStaticBoxSizer(colorBox, wxVERTICAL);
+  colorBoxSizer->Add(colorSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *color1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(color1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *colorCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_FILL1_COLOR, Fill1Color,
+                   wxDefaultPosition, wxSize(80, 22));
+  color1Sizer->Add(colorCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxTextCtrl *sampleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_FILL1_PICKER_HEX, wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  wxColour back = wxColour(0, 0, 0);
+  sampleCtrl->SetBackgroundColour(back);
+  color1Sizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxBoxSizer *pickerSizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(pickerSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *pick =
+    new wxButton(panel, ID_SYMBOLIZER_FILL1_PICKER_BTN, wxT("&Pick a color"));
+  pickerSizer->Add(pick, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// third row C: GRID to select an External Graphic
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  fillSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *gridBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("External Graphic resources"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxHORIZONTAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl1 =
+    new wxGrid(panel, ID_SYMBOLIZER_FILL1_GRAPHIC, wxDefaultPosition,
+               wxSize(420, 150), wxALWAYS_SHOW_SB);
+  int count = 0;
+  ExternalGraphic *pE = List->GetFirst();
+  while (pE)
+    {
+      // counting how many lines are there
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl1->CreateGrid(count, 4, wxGrid::wxGridSelectRows);
+  GridCtrl1->SetColLabelValue(0, wxT("Graphic"));
+  GridCtrl1->SetColLabelValue(1, wxT("Title"));
+  GridCtrl1->SetColLabelValue(2, wxT("Abstract"));
+  GridCtrl1->SetColLabelValue(3, wxT("MimeType"));
+  count = 0;
+  pE = List->GetFirst();
+  while (pE)
+    {
+      // feeding grid rows
+      MyGraphicCellRenderer *renderer = new MyGraphicCellRenderer;
+      renderer->SetGraphic(pE->GetGraphic());
+      GridCtrl1->SetCellRenderer(count, 0, renderer);
+      GridCtrl1->SetCellValue(count, 1, pE->GetTitle());
+      GridCtrl1->SetCellValue(count, 2, pE->GetAbstract());
+      GridCtrl1->SetCellValue(count, 3, pE->GetMimeType());
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl1->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl1->AutoSize();
+  GridCtrl1->EnableEditing(false);
+  gridSizer->Add(GridCtrl1, 0, wxALIGN_RIGHT | wxALL, 5);
+  GridCtrl1->Enable(false);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// second row C: Color Replacement
+  wxBoxSizer *replacementBoxSizer = new wxBoxSizer(wxVERTICAL);
+  GridSizer->Add(replacementBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *replacementBox = new wxStaticBox(panel, wxID_STATIC,
+                                                wxT("Color Replacement"),
+                                                wxDefaultPosition,
+                                                wxDefaultSize);
+  wxBoxSizer *replacementSizer =
+    new wxStaticBoxSizer(replacementBox, wxVERTICAL);
+  replacementBoxSizer->Add(replacementSizer, 0,
+                           wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxCheckBox *enableReplacementCtrl =
+    new wxCheckBox(panel, ID_SYMBOLIZER_FILL1_ENABLE_REPLACEMENT,
+                   wxT("Enable"),
+                   wxDefaultPosition, wxDefaultSize);
+  enableReplacementCtrl->SetValue(false);
+  enableReplacementCtrl->Enable(false);
+  replacementSizer->Add(enableReplacementCtrl, 0,
+                        wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *replacement1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  replacementSizer->Add(replacement1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *replacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_FILL1_REPLACEMENT,
+                   Fill1ColorReplacement,
+                   wxDefaultPosition, wxSize(80, 22));
+  replacement1Sizer->Add(replacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  replacementCtrl->Enable(false);
+  wxTextCtrl *sampleReplacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_FILL1_REPLACEMENT_HEX,
+                   wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  back = wxColour(0, 0, 0);
+  sampleReplacementCtrl->SetBackgroundColour(back);
+  replacement1Sizer->Add(sampleReplacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_FILL1_ENABLE, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdFill1Changed);
+  Connect(ID_SYMBOLIZER_FILL1_TYPE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdFill1TypeChanged);
+  Connect(ID_SYMBOLIZER_FILL1_COLOR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdColor1Changed);
+  Connect(ID_SYMBOLIZER_FILL1_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdColor1Picker);
+  Connect(ID_SYMBOLIZER_FILL1_ENABLE_REPLACEMENT,
+          wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdFill1EnableReplacementChanged);
+  Connect(ID_SYMBOLIZER_FILL1_REPLACEMENT, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdFill1ReplacementChanged);
+  return panel;
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdFill1Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Fill #1 enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_FILL1_ENABLE);
+  if (enableCtrl->IsChecked() == true)
+    EnableFill1 = true;
+  else
+    EnableFill1 = false;
+  RetrieveFill1Page(false);
+  UpdateFill1Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdFill1TypeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Fill Type changed: updating the visual sample
+//
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_FILL1_TYPE);
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL1_COLOR);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_FILL1_PICKER_BTN);
+  if (typeBox->GetSelection() == 0)
+    HasGraphicFill1 = false;
+  else
+    HasGraphicFill1 = true;
+  RetrieveFill1Page(false);
+  UpdateFill1Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdColor1Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Fill color changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL1_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL1_PICKER_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdColor1Picker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL1_COLOR);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdFill1EnableReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Polygon #1 Fill ColorReplacement enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_FILL1_ENABLE_REPLACEMENT);
+  if (enableCtrl->IsChecked() == true)
+    EnableFill1Replacement = true;
+  else
+    EnableFill1Replacement = false;
+  RetrieveFill1Page(false);
+  UpdateFill1Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdFill1ReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Color Replacement changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL1_REPLACEMENT);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL1_REPLACEMENT_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+wxPanel *SimplePolygonSymbolizerDialog::CreateStroke1Page(wxWindow * parent)
+{
+//
+// creating the STROKE #1 page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_STROKE1);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+// first row A: the Stroke #1 Opacity 
+  wxBoxSizer *opacityBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *enableBox = new wxStaticBox(panel, wxID_STATIC,
+                                           wxT("Stroke"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize);
+  wxBoxSizer *enableSizer = new wxStaticBoxSizer(enableBox, wxVERTICAL);
+  opacityBoxSizer->Add(enableSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxCheckBox *enableCtrl = new wxCheckBox(panel, ID_SYMBOLIZER_STROKE1_ENABLE,
+                                          wxT("Enable"),
+                                          wxDefaultPosition, wxDefaultSize);
+  enableCtrl->SetValue(true);
+  enableSizer->Add(enableCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *opacityBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("Opacity"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *opacitySizer = new wxStaticBoxSizer(opacityBox, wxVERTICAL);
+  opacityBoxSizer->Add(opacitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxSlider *opacityCtrl =
+    new wxSlider(panel, ID_SYMBOLIZER_STROKE1_OPACITY, 100, 0, 100,
+                 wxDefaultPosition, wxSize(600, 45),
+                 wxSL_HORIZONTAL | wxSL_LABELS);
+  opacityCtrl->Enable(false);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// second row: Stroke color or Graphic
+  wxBoxSizer *strokeSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(strokeSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// second row A: Stroke Type
+  wxBoxSizer *stroke1Sizer = new wxBoxSizer(wxVERTICAL);
+  strokeSizer->Add(stroke1Sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxString type[2];
+  type[0] = wxT("&Color");
+  type[1] = wxT("&Graphic");
+  wxRadioBox *typeBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE1_TYPE,
+                                       wxT("&Stroke Type"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 2,
+                                       type, 1,
+                                       wxRA_SPECIFY_ROWS);
+  stroke1Sizer->Add(typeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  typeBox->SetSelection(0);
+  typeBox->Enable(false);
+// second row B: Stroke Color
+  wxBoxSizer *colorBoxSizer = new wxBoxSizer(wxVERTICAL);
+  stroke1Sizer->Add(colorBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *colorBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Stroke Color"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *colorSizer = new wxStaticBoxSizer(colorBox, wxVERTICAL);
+  colorBoxSizer->Add(colorSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *color1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(color1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *colorCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_COLOR, Stroke1Color,
+                   wxDefaultPosition, wxSize(80, 22));
+  colorCtrl->Enable(false);
+  color1Sizer->Add(colorCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxTextCtrl *sampleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_PICKER_HEX, wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  wxColour back = wxColour(0, 0, 0);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Enable(false);
+  color1Sizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxBoxSizer *pickerSizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(pickerSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *pick =
+    new wxButton(panel, ID_SYMBOLIZER_STROKE1_PICKER_BTN, wxT("&Pick a color"));
+  pick->Enable(false);
+  pickerSizer->Add(pick, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// second row C: GRID to select an External Graphic
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  strokeSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *gridBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("External Graphic resources"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxHORIZONTAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl2 =
+    new wxGrid(panel, ID_SYMBOLIZER_STROKE1_GRAPHIC, wxDefaultPosition,
+               wxSize(420, 150), wxALWAYS_SHOW_SB);
+  int count = 0;
+  ExternalGraphic *pE = List->GetFirst();
+  while (pE)
+    {
+      // counting how many lines are there
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl2->CreateGrid(count, 4, wxGrid::wxGridSelectRows);
+  GridCtrl2->SetColLabelValue(0, wxT("Graphic"));
+  GridCtrl2->SetColLabelValue(1, wxT("Title"));
+  GridCtrl2->SetColLabelValue(2, wxT("Abstract"));
+  GridCtrl2->SetColLabelValue(3, wxT("MimeType"));
+  count = 0;
+  pE = List->GetFirst();
+  while (pE)
+    {
+      // feeding grid rows
+      MyGraphicCellRenderer *renderer = new MyGraphicCellRenderer;
+      renderer->SetGraphic(pE->GetGraphic());
+      GridCtrl2->SetCellRenderer(count, 0, renderer);
+      GridCtrl2->SetCellValue(count, 1, pE->GetTitle());
+      GridCtrl2->SetCellValue(count, 2, pE->GetAbstract());
+      GridCtrl2->SetCellValue(count, 3, pE->GetMimeType());
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl2->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl2->AutoSize();
+  GridCtrl2->EnableEditing(false);
+  gridSizer->Add(GridCtrl2, 0, wxALIGN_RIGHT | wxALL, 5);
+  GridCtrl2->Enable(false);
+// second row C: Color Replacement
+  wxBoxSizer *replacementBoxSizer = new wxBoxSizer(wxVERTICAL);
+  GridSizer->Add(replacementBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *replacementBox = new wxStaticBox(panel, wxID_STATIC,
+                                                wxT("Color Replacement"),
+                                                wxDefaultPosition,
+                                                wxDefaultSize);
+  wxBoxSizer *replacementSizer =
+    new wxStaticBoxSizer(replacementBox, wxVERTICAL);
+  replacementBoxSizer->Add(replacementSizer, 0,
+                           wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxCheckBox *enableReplacementCtrl =
+    new wxCheckBox(panel, ID_SYMBOLIZER_STROKE1_ENABLE_REPLACEMENT,
+                   wxT("Enable"),
+                   wxDefaultPosition, wxDefaultSize);
+  enableReplacementCtrl->SetValue(false);
+  enableReplacementCtrl->Enable(false);
+  replacementSizer->Add(enableReplacementCtrl, 0,
+                        wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *replacement1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  replacementSizer->Add(replacement1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *replacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_REPLACEMENT,
+                   Stroke1ColorReplacement,
+                   wxDefaultPosition, wxSize(80, 22));
+  replacement1Sizer->Add(replacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  replacementCtrl->Enable(false);
+  wxTextCtrl *sampleReplacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_REPLACEMENT_HEX,
+                   wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  back = wxColour(0, 0, 0);
+  sampleReplacementCtrl->SetBackgroundColour(back);
+  replacement1Sizer->Add(sampleReplacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: Stroke-Width, Stroke-LineJoin, Stroke-LineCap and Stroke-Dasharray 
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// third row A: StrokeWidth
+  wxBoxSizer *widthBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(widthBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *widthBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Stroke Width"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *widthSizer = new wxStaticBoxSizer(widthBox, wxVERTICAL);
+  widthBoxSizer->Add(widthSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxTextCtrl *widthCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_WIDTH, wxT("1.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  widthCtrl->Enable(false);
+  widthSizer->Add(widthCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// third row B: LineJoin
+  wxString join[3];
+  join[0] = wxT("&Mitre");
+  join[1] = wxT("&Round");
+  join[2] = wxT("&Bevel");
+  wxRadioBox *joinBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE1_LINEJOIN,
+                                       wxT("&Line Join"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 3,
+                                       join, 1,
+                                       wxRA_SPECIFY_COLS);
+  miscSizer->Add(joinBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  joinBox->SetSelection(1);
+  joinBox->Enable(false);
+// third row C: LineCap
+  wxString cap[3];
+  cap[0] = wxT("&Butt");
+  cap[1] = wxT("&Round");
+  cap[2] = wxT("&Square");
+  wxRadioBox *capBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE1_LINECAP,
+                                      wxT("&Line Cap"),
+                                      wxDefaultPosition,
+                                      wxDefaultSize, 3,
+                                      cap, 1,
+                                      wxRA_SPECIFY_COLS);
+  miscSizer->Add(capBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  capBox->SetSelection(1);
+  capBox->Enable(false);
+// third row D: DashArray and DashOffset
+  wxBoxSizer *dashBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(dashBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *dashBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("Dashed/Dotted Stroke"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *dashSizer = new wxStaticBoxSizer(dashBox, wxVERTICAL);
+  dashBoxSizer->Add(dashSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *dash1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  dashSizer->Add(dash1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *dash1Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT("Dash Array:"));
+  dash1Sizer->Add(dash1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *dashArrayCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_DASHARRAY, wxT(""),
+                   wxDefaultPosition, wxSize(200, 22));
+  dashArrayCtrl->Enable(false);
+  dash1Sizer->Add(dashArrayCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxStaticText *dash2Label =
+    new wxStaticText(panel, wxID_STATIC, wxT("e.g. 10,3,2,3"));
+  dash2Label->SetForegroundColour(wxColour(255, 0, 0));
+  dash1Sizer->Add(dash2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *dash2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  dashSizer->Add(dash2Sizer, 0, wxALIGN_LEFT | wxALL, 0);
+  wxStaticText *dashOffsetLabel = new wxStaticText(panel, wxID_STATIC,
+                                                   wxT("Dash Offset:"));
+  dash2Sizer->Add(dashOffsetLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *dashOffsetCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE1_DASHOFFSET, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  dashOffsetCtrl->Enable(false);
+  dash2Sizer->Add(dashOffsetCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_STROKE1_ENABLE, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdStroke1Changed);
+  Connect(ID_SYMBOLIZER_STROKE1_TYPE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdStroke1TypeChanged);
+  Connect(ID_SYMBOLIZER_STROKE1_COLOR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdColor2Changed);
+  Connect(ID_SYMBOLIZER_STROKE1_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdColor2Picker);
+  Connect(ID_SYMBOLIZER_STROKE1_ENABLE_REPLACEMENT,
+          wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdStroke1EnableReplacementChanged);
+  Connect(ID_SYMBOLIZER_STROKE1_REPLACEMENT, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdStroke1ReplacementChanged);
+  Connect(ID_SYMBOLIZER_STROKE1_LINEJOIN, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdLineJoin1Changed);
+  Connect(ID_SYMBOLIZER_STROKE1_LINECAP, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdLineCap1Changed);
+  return panel;
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdStroke1Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke #1 enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE1_ENABLE);
+  if (enableCtrl->IsChecked() == true)
+    EnableStroke1 = true;
+  else
+    EnableStroke1 = false;
+  RetrieveStroke1Page(false);
+  UpdateStroke1Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdStroke1TypeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// stroke type changed: updating the visual sample
+//
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE1_TYPE);
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_COLOR);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_STROKE1_PICKER_BTN);
+  if (typeBox->GetSelection() == 0)
+    HasGraphicStroke1 = false;
+  else
+    HasGraphicStroke1 = true;
+  RetrieveStroke1Page(false);
+  UpdateStroke1Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdColor2Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke color changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_PICKER_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdColor2Picker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_COLOR);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdStroke1EnableReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Polygon #1 Stroke ColorReplacement enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE1_ENABLE_REPLACEMENT);
+  if (enableCtrl->IsChecked() == true)
+    EnableStroke1Replacement = true;
+  else
+    EnableStroke1Replacement = false;
+  RetrieveStroke1Page(false);
+  UpdateStroke1Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdStroke1ReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Color Replacement changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_REPLACEMENT);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_REPLACEMENT_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdLineJoin1Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// LineJoin selection changed
+//
+  wxRadioBox *lineJoinCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE1_LINEJOIN);
+  switch (lineJoinCtrl->GetSelection())
+    {
+      case 0:
+        Stroke1LineJoin = RL2_PEN_JOIN_MITER;
+        break;
+      case 2:
+        Stroke1LineJoin = RL2_PEN_JOIN_BEVEL;
+        break;
+      default:
+        Stroke1LineJoin = RL2_PEN_JOIN_ROUND;
+        break;
+    };
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdLineCap1Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// LineCap selection changed
+//
+  wxRadioBox *lineCapCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE1_LINECAP);
+  switch (lineCapCtrl->GetSelection())
+    {
+      case 0:
+        Stroke1LineCap = RL2_PEN_CAP_BUTT;
+        break;
+      case 2:
+        Stroke1LineCap = RL2_PEN_CAP_SQUARE;
+        break;
+      default:
+        Stroke1LineCap = RL2_PEN_CAP_ROUND;
+        break;
+    };
+}
+
+wxPanel *SimplePolygonSymbolizerDialog::CreateFill2Page(wxWindow * parent)
+{
+//
+// creating the Polygon #2 Fill page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_FILL2);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+// first row: the Polygon #2 Displacement and Perpendicular Offset
+  wxBoxSizer *polygonBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(polygonBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *polygonBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("Polygon #2"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *polygonSizer = new wxStaticBoxSizer(polygonBox, wxHORIZONTAL);
+  polygonBoxSizer->Add(polygonSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxCheckBox *polygon2Ctrl =
+    new wxCheckBox(panel, ID_SYMBOLIZER_POLYGON2_ENABLE,
+                   wxT("Enable"),
+                   wxDefaultPosition, wxDefaultSize);
+  polygon2Ctrl->SetValue(false);
+  polygonSizer->Add(polygon2Ctrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// first row A: Displacement
+  wxBoxSizer *displacementBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  polygonSizer->Add(displacementBoxSizer, 0,
+                    wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *displacementBox = new wxStaticBox(panel, wxID_STATIC,
+                                                 wxT("Displacement"),
+                                                 wxDefaultPosition,
+                                                 wxDefaultSize);
+  wxBoxSizer *displacementSizer =
+    new wxStaticBoxSizer(displacementBox, wxVERTICAL);
+  displacementBoxSizer->Add(displacementSizer, 0,
+                            wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *displ1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  displacementSizer->Add(displ1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *displ1Label = new wxStaticText(panel, wxID_STATIC, wxT("X"));
+  displ1Sizer->Add(displ1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxTextCtrl *displacementXCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_POLYGON2_DISPLACEMENT_X, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  displ1Sizer->Add(displacementXCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  displacementXCtrl->Enable(false);
+  wxBoxSizer *displ2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  displacementSizer->Add(displ2Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *displ2Label = new wxStaticText(panel, wxID_STATIC, wxT("Y"));
+  displ2Sizer->Add(displ2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxTextCtrl *displacementYCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_POLYGON2_DISPLACEMENT_Y, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  displ2Sizer->Add(displacementYCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  displacementYCtrl->Enable(false);
+// first row B: PerpendicularOffset
+  wxBoxSizer *perpendicularBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  polygonSizer->Add(perpendicularBoxSizer, 0,
+                    wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *perpendicularBox = new wxStaticBox(panel, wxID_STATIC,
+                                                  wxT("Perpendicular Offset"),
+                                                  wxDefaultPosition,
+                                                  wxDefaultSize);
+  wxBoxSizer *perpendicularSizer =
+    new wxStaticBoxSizer(perpendicularBox, wxVERTICAL);
+  perpendicularBoxSizer->Add(perpendicularSizer, 0,
+                             wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *perp1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  perpendicularSizer->Add(perp1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxTextCtrl *perpendicularCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_POLYGON2_PERPENDICULAR, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  perp1Sizer->Add(perpendicularCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  perpendicularCtrl->Enable(false);
+  wxStaticText *perp1Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT
+                                              ("Positive: larger. / Negative: smaller."));
+  perp1Sizer->Add(perp1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxStaticText *perp2Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT
+                                              ("Drawing polygons smaller or larger than their actual geometry (Buffer)."));
+  perpendicularSizer->Add(perp2Label, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// second row: Fill#1 Opacity
+  wxBoxSizer *auxBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(auxBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *auxBox = new wxStaticBox(panel, wxID_STATIC,
+                                        wxT("Polygon #2 Fill"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize);
+  wxBoxSizer *auxSizer = new wxStaticBoxSizer(auxBox, wxVERTICAL);
+  auxBoxSizer->Add(auxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *enableSizer = new wxBoxSizer(wxHORIZONTAL);
+  auxSizer->Add(enableSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxCheckBox *enableCtrl = new wxCheckBox(panel, ID_SYMBOLIZER_FILL2_ENABLE,
+                                          wxT("Enable"),
+                                          wxDefaultPosition, wxDefaultSize);
+  enableCtrl->SetValue(false);
+  enableCtrl->Enable(false);
+  enableSizer->Add(enableCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *opacityBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  enableSizer->Add(opacityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *opacityBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("Opacity"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *opacitySizer = new wxStaticBoxSizer(opacityBox, wxVERTICAL);
+  opacityBoxSizer->Add(opacitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxSlider *opacityCtrl =
+    new wxSlider(panel, ID_SYMBOLIZER_FILL2_OPACITY, 100, 0, 100,
+                 wxDefaultPosition, wxSize(600, 45),
+                 wxSL_HORIZONTAL | wxSL_LABELS);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// third row: Fill color or Graphic
+  wxBoxSizer *fillSizer = new wxBoxSizer(wxHORIZONTAL);
+  auxSizer->Add(fillSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// third row A: Fill Type
+  wxBoxSizer *fill1Sizer = new wxBoxSizer(wxVERTICAL);
+  fillSizer->Add(fill1Sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxString type[2];
+  type[0] = wxT("&Color");
+  type[1] = wxT("&Graphic");
+  wxRadioBox *typeBox = new wxRadioBox(panel, ID_SYMBOLIZER_FILL2_TYPE,
+                                       wxT("&Fill Type"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 2,
+                                       type, 1,
+                                       wxRA_SPECIFY_ROWS);
+  fill1Sizer->Add(typeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  typeBox->SetSelection(0);
+// third row B: Fill Color
+  wxBoxSizer *colorBoxSizer = new wxBoxSizer(wxVERTICAL);
+  fill1Sizer->Add(colorBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *colorBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Fill Color"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *colorSizer = new wxStaticBoxSizer(colorBox, wxVERTICAL);
+  colorBoxSizer->Add(colorSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *color1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(color1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *colorCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_FILL2_COLOR, Fill2Color,
+                   wxDefaultPosition, wxSize(80, 22));
+  color1Sizer->Add(colorCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxTextCtrl *sampleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_FILL2_PICKER_HEX, wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  wxColour back = wxColour(0, 0, 0);
+  sampleCtrl->SetBackgroundColour(back);
+  color1Sizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxBoxSizer *pickerSizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(pickerSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *pick =
+    new wxButton(panel, ID_SYMBOLIZER_FILL2_PICKER_BTN, wxT("&Pick a color"));
+  pickerSizer->Add(pick, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// third row C: GRID to select an External Graphic
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  fillSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *gridBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("External Graphic resources"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxHORIZONTAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl3 =
+    new wxGrid(panel, ID_SYMBOLIZER_FILL2_GRAPHIC, wxDefaultPosition,
+               wxSize(420, 150), wxALWAYS_SHOW_SB);
+  int count = 0;
+  ExternalGraphic *pE = List->GetFirst();
+  while (pE)
+    {
+      // counting how many lines are there
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl3->CreateGrid(count, 4, wxGrid::wxGridSelectRows);
+  GridCtrl3->SetColLabelValue(0, wxT("Graphic"));
+  GridCtrl3->SetColLabelValue(1, wxT("Title"));
+  GridCtrl3->SetColLabelValue(2, wxT("Abstract"));
+  GridCtrl3->SetColLabelValue(3, wxT("MimeType"));
+  count = 0;
+  pE = List->GetFirst();
+  while (pE)
+    {
+      // feeding grid rows
+      MyGraphicCellRenderer *renderer = new MyGraphicCellRenderer;
+      renderer->SetGraphic(pE->GetGraphic());
+      GridCtrl3->SetCellRenderer(count, 0, renderer);
+      GridCtrl3->SetCellValue(count, 1, pE->GetTitle());
+      GridCtrl3->SetCellValue(count, 2, pE->GetAbstract());
+      GridCtrl3->SetCellValue(count, 3, pE->GetMimeType());
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl3->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl3->AutoSize();
+  GridCtrl3->EnableEditing(false);
+  gridSizer->Add(GridCtrl3, 0, wxALIGN_RIGHT | wxALL, 5);
+  GridCtrl3->Enable(false);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// second row C: Color Replacement
+  wxBoxSizer *replacementBoxSizer = new wxBoxSizer(wxVERTICAL);
+  GridSizer->Add(replacementBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *replacementBox = new wxStaticBox(panel, wxID_STATIC,
+                                                wxT("Color Replacement"),
+                                                wxDefaultPosition,
+                                                wxDefaultSize);
+  wxBoxSizer *replacementSizer =
+    new wxStaticBoxSizer(replacementBox, wxVERTICAL);
+  replacementBoxSizer->Add(replacementSizer, 0,
+                           wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxCheckBox *enableReplacementCtrl =
+    new wxCheckBox(panel, ID_SYMBOLIZER_FILL2_ENABLE_REPLACEMENT,
+                   wxT("Enable"),
+                   wxDefaultPosition, wxDefaultSize);
+  enableReplacementCtrl->SetValue(false);
+  enableReplacementCtrl->Enable(false);
+  replacementSizer->Add(enableReplacementCtrl, 0,
+                        wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *replacement1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  replacementSizer->Add(replacement1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *replacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_FILL2_REPLACEMENT,
+                   Fill2ColorReplacement,
+                   wxDefaultPosition, wxSize(80, 22));
+  replacement1Sizer->Add(replacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  replacementCtrl->Enable(false);
+  wxTextCtrl *sampleReplacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_FILL2_REPLACEMENT_HEX,
+                   wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  back = wxColour(0, 0, 0);
+  sampleReplacementCtrl->SetBackgroundColour(back);
+  replacement1Sizer->Add(sampleReplacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_POLYGON2_ENABLE, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdPolygon2Changed);
+  Connect(ID_SYMBOLIZER_FILL2_ENABLE, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdFill2Changed);
+  Connect(ID_SYMBOLIZER_FILL2_TYPE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdFill2TypeChanged);
+  Connect(ID_SYMBOLIZER_FILL2_COLOR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdColor3Changed);
+  Connect(ID_SYMBOLIZER_FILL2_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdColor3Picker);
+  Connect(ID_SYMBOLIZER_FILL2_ENABLE_REPLACEMENT,
+          wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdFill2EnableReplacementChanged);
+  Connect(ID_SYMBOLIZER_FILL2_REPLACEMENT, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdFill2ReplacementChanged);
+  return panel;
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdPolygon2Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Polygon #2 enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_POLYGON2_ENABLE);
+  if (enableCtrl->IsChecked() == true)
+    EnablePolygon2 = true;
+  else
+    EnablePolygon2 = false;
+  RetrieveFill2Page(false);
+  UpdateFill2Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdFill2Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Fill #2 enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_FILL2_ENABLE);
+  if (enableCtrl->IsChecked() == true)
+    EnableFill2 = true;
+  else
+    EnableFill2 = false;
+  RetrieveFill2Page(false);
+  UpdateFill2Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdFill2TypeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Fill Type changed: updating the visual sample
+//
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_FILL2_TYPE);
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL2_COLOR);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_FILL2_PICKER_BTN);
+  if (typeBox->GetSelection() == 0)
+    HasGraphicFill2 = false;
+  else
+    HasGraphicFill2 = true;
+  RetrieveFill2Page(false);
+  UpdateFill2Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdColor3Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Fill color changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL2_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL2_PICKER_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdColor3Picker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL2_COLOR);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdFill2EnableReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Polygon #2 Stroke ColorReplacement enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_FILL2_ENABLE_REPLACEMENT);
+  if (enableCtrl->IsChecked() == true)
+    EnableFill2Replacement = true;
+  else
+    EnableFill2Replacement = false;
+  RetrieveFill2Page(false);
+  UpdateFill2Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdFill2ReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Color Replacement changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL2_REPLACEMENT);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL2_REPLACEMENT_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+wxPanel *SimplePolygonSymbolizerDialog::CreateStroke2Page(wxWindow * parent)
+{
+//
+// creating the STROKE #2 page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_STROKE2);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+// first row A: the Stroke #1 Opacity 
+  wxBoxSizer *opacityBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *enableBox = new wxStaticBox(panel, wxID_STATIC,
+                                           wxT("Stroke"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize);
+  wxBoxSizer *enableSizer = new wxStaticBoxSizer(enableBox, wxVERTICAL);
+  opacityBoxSizer->Add(enableSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxCheckBox *enableCtrl = new wxCheckBox(panel, ID_SYMBOLIZER_STROKE2_ENABLE,
+                                          wxT("Enable"),
+                                          wxDefaultPosition, wxDefaultSize);
+  enableCtrl->SetValue(false);
+  enableCtrl->Enable(false);
+  enableSizer->Add(enableCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *opacityBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("Opacity"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *opacitySizer = new wxStaticBoxSizer(opacityBox, wxVERTICAL);
+  opacityBoxSizer->Add(opacitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxSlider *opacityCtrl =
+    new wxSlider(panel, ID_SYMBOLIZER_STROKE2_OPACITY, 100, 0, 100,
+                 wxDefaultPosition, wxSize(600, 45),
+                 wxSL_HORIZONTAL | wxSL_LABELS);
+  opacityCtrl->Enable(false);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// second row: Stroke color or Graphic
+  wxBoxSizer *strokeSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(strokeSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// second row A: Stroke Type
+  wxBoxSizer *stroke1Sizer = new wxBoxSizer(wxVERTICAL);
+  strokeSizer->Add(stroke1Sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxString type[2];
+  type[0] = wxT("&Color");
+  type[1] = wxT("&Graphic");
+  wxRadioBox *typeBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE2_TYPE,
+                                       wxT("&Stroke Type"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 2,
+                                       type, 1,
+                                       wxRA_SPECIFY_ROWS);
+  stroke1Sizer->Add(typeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  typeBox->SetSelection(0);
+  typeBox->Enable(false);
+// second row B: Stroke Color
+  wxBoxSizer *colorBoxSizer = new wxBoxSizer(wxVERTICAL);
+  stroke1Sizer->Add(colorBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *colorBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Stroke Color"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *colorSizer = new wxStaticBoxSizer(colorBox, wxVERTICAL);
+  colorBoxSizer->Add(colorSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *color1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(color1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *colorCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_COLOR, Stroke2Color,
+                   wxDefaultPosition, wxSize(80, 22));
+  colorCtrl->Enable(false);
+  color1Sizer->Add(colorCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxTextCtrl *sampleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_PICKER_HEX, wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  wxColour back = wxColour(0, 0, 0);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Enable(false);
+  color1Sizer->Add(sampleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxBoxSizer *pickerSizer = new wxBoxSizer(wxHORIZONTAL);
+  colorSizer->Add(pickerSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *pick =
+    new wxButton(panel, ID_SYMBOLIZER_STROKE2_PICKER_BTN, wxT("&Pick a color"));
+  pick->Enable(false);
+  pickerSizer->Add(pick, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// second row C: GRID to select an External Graphic
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  strokeSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *gridBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("External Graphic resources"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxHORIZONTAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl4 =
+    new wxGrid(panel, ID_SYMBOLIZER_STROKE2_GRAPHIC, wxDefaultPosition,
+               wxSize(420, 150), wxALWAYS_SHOW_SB);
+  int count = 0;
+  ExternalGraphic *pE = List->GetFirst();
+  while (pE)
+    {
+      // counting how many lines are there
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl4->CreateGrid(count, 4, wxGrid::wxGridSelectRows);
+  GridCtrl4->SetColLabelValue(0, wxT("Graphic"));
+  GridCtrl4->SetColLabelValue(1, wxT("Title"));
+  GridCtrl4->SetColLabelValue(2, wxT("Abstract"));
+  GridCtrl4->SetColLabelValue(3, wxT("MimeType"));
+  count = 0;
+  pE = List->GetFirst();
+  while (pE)
+    {
+      // feeding grid rows
+      MyGraphicCellRenderer *renderer = new MyGraphicCellRenderer;
+      renderer->SetGraphic(pE->GetGraphic());
+      GridCtrl4->SetCellRenderer(count, 0, renderer);
+      GridCtrl4->SetCellValue(count, 1, pE->GetTitle());
+      GridCtrl4->SetCellValue(count, 2, pE->GetAbstract());
+      GridCtrl4->SetCellValue(count, 3, pE->GetMimeType());
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl4->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl4->AutoSize();
+  GridCtrl4->EnableEditing(false);
+  gridSizer->Add(GridCtrl4, 0, wxALIGN_RIGHT | wxALL, 5);
+  GridCtrl4->Enable(false);
+// second row C: Color Replacement
+  wxBoxSizer *replacementBoxSizer = new wxBoxSizer(wxVERTICAL);
+  GridSizer->Add(replacementBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *replacementBox = new wxStaticBox(panel, wxID_STATIC,
+                                                wxT("Color Replacement"),
+                                                wxDefaultPosition,
+                                                wxDefaultSize);
+  wxBoxSizer *replacementSizer =
+    new wxStaticBoxSizer(replacementBox, wxVERTICAL);
+  replacementBoxSizer->Add(replacementSizer, 0,
+                           wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxCheckBox *enableReplacementCtrl =
+    new wxCheckBox(panel, ID_SYMBOLIZER_STROKE2_ENABLE_REPLACEMENT,
+                   wxT("Enable"),
+                   wxDefaultPosition, wxDefaultSize);
+  enableReplacementCtrl->SetValue(false);
+  enableReplacementCtrl->Enable(false);
+  replacementSizer->Add(enableReplacementCtrl, 0,
+                        wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *replacement1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  replacementSizer->Add(replacement1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *replacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_REPLACEMENT,
+                   Stroke2ColorReplacement,
+                   wxDefaultPosition, wxSize(80, 22));
+  replacement1Sizer->Add(replacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  replacementCtrl->Enable(false);
+  wxTextCtrl *sampleReplacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_REPLACEMENT_HEX,
+                   wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  back = wxColour(0, 0, 0);
+  sampleReplacementCtrl->SetBackgroundColour(back);
+  replacement1Sizer->Add(sampleReplacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: Stroke-Width, Stroke-LineJoin, Stroke-LineCap and Stroke-Dasharray 
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// third row A: StrokeWidth
+  wxBoxSizer *widthBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(widthBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *widthBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Stroke Width"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *widthSizer = new wxStaticBoxSizer(widthBox, wxVERTICAL);
+  widthBoxSizer->Add(widthSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxTextCtrl *widthCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_WIDTH, wxT("1.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  widthCtrl->Enable(false);
+  widthSizer->Add(widthCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// third row B: LineJoin
+  wxString join[3];
+  join[0] = wxT("&Mitre");
+  join[1] = wxT("&Round");
+  join[2] = wxT("&Bevel");
+  wxRadioBox *joinBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE2_LINEJOIN,
+                                       wxT("&Line Join"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 3,
+                                       join, 1,
+                                       wxRA_SPECIFY_COLS);
+  miscSizer->Add(joinBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  joinBox->SetSelection(1);
+  joinBox->Enable(false);
+// third row C: LineCap
+  wxString cap[3];
+  cap[0] = wxT("&Butt");
+  cap[1] = wxT("&Round");
+  cap[2] = wxT("&Square");
+  wxRadioBox *capBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE2_LINECAP,
+                                      wxT("&Line Cap"),
+                                      wxDefaultPosition,
+                                      wxDefaultSize, 3,
+                                      cap, 1,
+                                      wxRA_SPECIFY_COLS);
+  miscSizer->Add(capBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  capBox->SetSelection(1);
+  capBox->Enable(false);
+// third row D: DashArray and DashOffset
+  wxBoxSizer *dashBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(dashBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *dashBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("Dashed/Dotted Stroke"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *dashSizer = new wxStaticBoxSizer(dashBox, wxVERTICAL);
+  dashBoxSizer->Add(dashSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *dash1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  dashSizer->Add(dash1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *dash1Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT("Dash Array:"));
+  dash1Sizer->Add(dash1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *dashArrayCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_DASHARRAY, wxT(""),
+                   wxDefaultPosition, wxSize(200, 22));
+  dashArrayCtrl->Enable(false);
+  dash1Sizer->Add(dashArrayCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxStaticText *dash2Label =
+    new wxStaticText(panel, wxID_STATIC, wxT("e.g. 10,3,2,3"));
+  dash2Label->SetForegroundColour(wxColour(255, 0, 0));
+  dash1Sizer->Add(dash2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *dash2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  dashSizer->Add(dash2Sizer, 0, wxALIGN_LEFT | wxALL, 0);
+  wxStaticText *dashOffsetLabel = new wxStaticText(panel, wxID_STATIC,
+                                                   wxT("Dash Offset:"));
+  dash2Sizer->Add(dashOffsetLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *dashOffsetCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE2_DASHOFFSET, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  dashOffsetCtrl->Enable(false);
+  dash2Sizer->Add(dashOffsetCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_STROKE2_ENABLE, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdStroke2Changed);
+  Connect(ID_SYMBOLIZER_STROKE2_TYPE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdStroke2TypeChanged);
+  Connect(ID_SYMBOLIZER_STROKE2_COLOR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdColor4Changed);
+  Connect(ID_SYMBOLIZER_STROKE2_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdColor4Picker);
+  Connect(ID_SYMBOLIZER_STROKE2_ENABLE_REPLACEMENT,
+          wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdStroke2EnableReplacementChanged);
+  Connect(ID_SYMBOLIZER_STROKE2_REPLACEMENT, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdStroke2ReplacementChanged);
+  Connect(ID_SYMBOLIZER_STROKE2_LINEJOIN, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdLineJoin2Changed);
+  Connect(ID_SYMBOLIZER_STROKE2_LINECAP, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdLineCap2Changed);
+  return panel;
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdStroke2Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke #2 enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE2_ENABLE);
+  if (enableCtrl->IsChecked() == true)
+    EnableStroke2 = true;
+  else
+    EnableStroke2 = false;
+  RetrieveStroke2Page(false);
+  UpdateStroke2Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdStroke2TypeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// stroke type changed: updating the visual sample
+//
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE2_TYPE);
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_COLOR);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_STROKE2_PICKER_BTN);
+  if (typeBox->GetSelection() == 0)
+    HasGraphicStroke2 = false;
+  else
+    HasGraphicStroke2 = true;
+  RetrieveStroke2Page(false);
+  UpdateStroke2Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdColor4Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke color changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_PICKER_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdColor4Picker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_COLOR);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdStroke2EnableReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Polygon #2 Stroke ColorReplacement enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE2_ENABLE_REPLACEMENT);
+  if (enableCtrl->IsChecked() == true)
+    EnableStroke2Replacement = true;
+  else
+    EnableStroke2Replacement = false;
+  RetrieveStroke2Page(false);
+  UpdateStroke2Page();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdStroke2ReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Color Replacement changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_REPLACEMENT);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_REPLACEMENT_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdLineJoin2Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// LineJoin selection changed
+//
+  wxRadioBox *lineJoinCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE2_LINEJOIN);
+  switch (lineJoinCtrl->GetSelection())
+    {
+      case 0:
+        Stroke2LineJoin = RL2_PEN_JOIN_MITER;
+        break;
+      case 2:
+        Stroke2LineJoin = RL2_PEN_JOIN_BEVEL;
+        break;
+      default:
+        Stroke2LineJoin = RL2_PEN_JOIN_ROUND;
+        break;
+    };
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdLineCap2Changed(wxCommandEvent & WXUNUSED(event))
+{
+//
+// LineCap selection changed
+//
+  wxRadioBox *lineCapCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE2_LINECAP);
+  switch (lineCapCtrl->GetSelection())
+    {
+      case 0:
+        Stroke2LineCap = RL2_PEN_CAP_BUTT;
+        break;
+      case 2:
+        Stroke2LineCap = RL2_PEN_CAP_SQUARE;
+        break;
+      default:
+        Stroke2LineCap = RL2_PEN_CAP_ROUND;
+        break;
+    };
+}
+
+wxPanel *SimplePolygonSymbolizerDialog::CreatePreviewPage(wxWindow * parent)
+{
+//
+// creating the Preview page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_PREVIEW);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxHORIZONTAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+  wxBoxSizer *previewBoxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(previewBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// creating a control to show the LineSymbolizer Preview
+  wxStaticBox *previewBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("PolygonSymbolizer Preview"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *previewSizer = new wxStaticBoxSizer(previewBox, wxVERTICAL);
+  previewBoxSizer->Add(previewSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  DrawPreview(500, 300);
+  SymbolizerPreview *previewCtrl =
+    new SymbolizerPreview(this, panel, ID_SYMBOLIZER_PREVIEW,
+                          PreviewBackBitmap, wxSize(500, 300));
+  previewSizer->Add(previewCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// Background selector
+  wxString back[3];
+  back[0] = wxT("&Checked");
+  back[1] = wxT("&White");
+  back[2] = wxT("&Black");
+  wxRadioBox *backBox = new wxRadioBox(panel, ID_SYMBOLIZER_BACKGROUND,
+                                       wxT("&Background"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 3,
+                                       back, 1,
+                                       wxRA_SPECIFY_COLS);
+  boxSizer->Add(backBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  backBox->SetSelection(0);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_BACKGROUND, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePolygonSymbolizerDialog::OnCmdBackgroundChanged);
+  return panel;
+}
+
+void SimplePolygonSymbolizerDialog::
+OnCmdBackgroundChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Preview Background selection changed
+//
+  wxRadioBox *backCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_BACKGROUND);
+  switch (backCtrl->GetSelection())
+    {
+      case 1:
+        PreviewBackground = GUI_PREVIEW_BACKGROUND_WHITE;
+        break;
+      case 2:
+        PreviewBackground = GUI_PREVIEW_BACKGROUND_BLACK;
+        break;
+      default:
+        PreviewBackground = GUI_PREVIEW_BACKGROUND_CHECKED;
+        break;
+    };
+  UpdatePreviewPage();
+}
+
+void SimplePolygonSymbolizerDialog::DrawPreview(int horz, int vert)
+{
+//
+// drawing a Symbolizer Preview
+//
+  PreviewBackBitmap.Create(horz, vert);
+  wxMemoryDC dc(PreviewBackBitmap);
+//
+// background filling
+//
+  wxImage img(24, 24);
+  for (int y = 0; y < 24; y++)
+    {
+      // creating a checked background
+      for (int x = 0; x < 24; x++)
+        {
+          if (y < 12)
+            {
+              if (x < 12)
+                img.SetRGB(x, y, 176, 176, 176);
+              else
+                img.SetRGB(x, y, 208, 208, 208);
+          } else
+            {
+              if (x < 12)
+                img.SetRGB(x, y, 208, 208, 208);
+              else
+                img.SetRGB(x, y, 176, 176, 176);
+            }
+        }
+    }
+  wxBrush stipple(img);
+  dc.SetBrush(stipple);
+  dc.DrawRectangle(0, 0, horz, vert);
+}
+
+void SimplePolygonSymbolizerDialog::CreateButtons()
+{
+// 
+// adding the common Buttons
+//
+  wxBoxSizer *topSizer = (wxBoxSizer *) (this->GetSizer());
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  topSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *insert =
+    new wxButton(this, ID_SYMBOLIZER_INSERT, wxT("&Insert into DBMS"));
+  btnBox->Add(insert, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *exp =
+    new wxButton(this, ID_SYMBOLIZER_EXPORT, wxT("&Export to file"));
+  btnBox->Add(exp, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *copy = new wxButton(this, ID_SYMBOLIZER_COPY, wxT("&Copy"));
+  btnBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+}
+
+bool SimplePolygonSymbolizerDialog::FinalValidityCheck()
+{
+//
+// last check before generating the SLD/SE Style
+//
+  if (Name.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the PolygonSymbolizer NAME !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  if (Title.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some PolygonSymbolizer TITLE is warmly suggested\n\n");
+      msg += wxT("Do you really confirm leaving an empty (undefined) Title ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  if (Abstract.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some PolygonSymbolizer ABSTRACT is warmly suggested\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an empty (undefined) Abstract ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  if (EnableFill1 == false && EnableStroke1 == false)
+    {
+      wxString msg =
+        wxT
+        ("Effectless Polygon #1 Style: both Fill and Stroke are disabled\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an effectless Polygon #1 Style ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  if (EnablePolygon2 == true && EnableFill2 == false && EnableStroke2 == false)
+    {
+      wxString msg =
+        wxT
+        ("Effectless Polygon #2 Style: both Fill and Stroke are disabled\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an effectless Polygon #2 Style ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  return true;
+}
+
+bool SimplePolygonSymbolizerDialog::RetrieveMainPage()
+{
+//
+// retrieving params from the MAIN page
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  Name = nameCtrl->GetValue();
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  Title = titleCtrl->GetValue();
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  Abstract = absCtrl->GetValue();
+  if (MinScale == true)
+    {
+      wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+      wxString value = minCtrl->GetValue();
+      if (value.ToDouble(&MinScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MinScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MaxScale == true)
+    {
+      wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+      wxString value = maxCtrl->GetValue();
+      if (value.ToDouble(&MaxScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MaxScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MinScale == true && MaxScale == true)
+    {
+      if (MinScaleDenominator >= MaxScaleDenominator)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE is always expected to be greater than MIN_SCALE !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  return true;
+}
+
+void SimplePolygonSymbolizerDialog::UpdateMainPage()
+{
+//
+// updating the MAIN page
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  nameCtrl->SetValue(Name);
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  titleCtrl->SetValue(Title);
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  absCtrl->SetValue(Abstract);
+  wxRadioBox *uomBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_UOM);
+  switch (Uom)
+    {
+      case GUI_UOM_METRE:
+        uomBox->SetSelection(1);
+        break;
+      case GUI_UOM_INCH:
+        uomBox->SetSelection(2);
+        break;
+      default:
+        uomBox->SetSelection(0);
+        break;
+    };
+  wxRadioBox *rangeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  if (MinScale != true && MaxScale != true)
+    rangeBox->SetSelection(0);
+  else if (MinScale == true && MaxScale != true)
+    rangeBox->SetSelection(1);
+  else if (MinScale != true && MaxScale == true)
+    rangeBox->SetSelection(2);
+  else
+    rangeBox->SetSelection(3);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  char dummy[64];
+  wxString str;
+  if (MinScale == true)
+    {
+      sprintf(dummy, "%1.2f", MinScaleDenominator);
+      str = wxString::FromUTF8(dummy);
+      minCtrl->SetValue(str);
+      minCtrl->Enable(true);
+  } else
+    {
+      str = wxT("0.0");
+      minCtrl->SetValue(str);
+      minCtrl->Enable(false);
+    }
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  if (MaxScale == true)
+    {
+      sprintf(dummy, "%1.2f", MaxScaleDenominator);
+      str = wxString::FromUTF8(dummy);
+      maxCtrl->SetValue(str);
+      maxCtrl->Enable(true);
+  } else
+    {
+      str = wxT("+Infinite");
+      maxCtrl->SetValue(str);
+      maxCtrl->Enable(false);
+    }
+}
+
+bool SimplePolygonSymbolizerDialog::RetrieveFill1Page(bool check)
+{
+//
+// retrieving params from the Polygon #1 Fill page
+//
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_FILL1_OPACITY);
+  Fill1Opacity = opacityCtrl->GetValue() / 100.0;
+  wxTextCtrl *displXCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_POLYGON1_DISPLACEMENT_X);
+  wxString value = displXCtrl->GetValue();
+  if (value.ToDouble(&DisplacementX1) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("DISPLACEMENT-X isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *displYCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_POLYGON1_DISPLACEMENT_Y);
+  value = displYCtrl->GetValue();
+  if (value.ToDouble(&DisplacementY1) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("DISPLACEMENT-Y isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *perpCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_POLYGON1_PERPENDICULAR);
+  value = perpCtrl->GetValue();
+  if (value.ToDouble(&PerpendicularOffset1) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("PERPENDICULAR-OFFSET isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (HasGraphicFill1 == false)
+    {
+      wxTextCtrl *colorCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL1_COLOR);
+      wxString color = colorCtrl->GetValue();
+      if (ColorMapEntry::IsValidColor(color) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("FILL-COLOR isn't a valid HexRGB color !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      Fill1Color = color;
+  } else
+    {
+      int selCount = 0;
+      int selected = -1;
+      for (int i = 0; i < GridCtrl1->GetNumberRows(); i++)
+        {
+          if (GridCtrl1->IsInSelection(i, 0) == true)
+            {
+              selected = i;
+              selCount++;
+            }
+        }
+      if (selCount < 1)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("You must select an External Graphic resource !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (selCount > 1)
+        {
+          if (check == true)
+            {
+              wxString msg =
+                wxT
+                ("You must select just a single External Graphic resource !!!\n");
+              msg += wxT("Multiple selection is not supported");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                           this);
+              return false;
+            }
+        }
+      List->FindByIndex(selected, Fill1XLinkHref, Fill1MimeType);
+      if (EnableFill1Replacement == true)
+        {
+          wxTextCtrl *replacementCtrl =
+            (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL1_REPLACEMENT);
+          wxString color = replacementCtrl->GetValue();
+          if (ColorMapEntry::IsValidColor(color) != true)
+            {
+              if (check == true)
+                {
+                  wxMessageBox(wxT
+                               ("COLOR-REPACEMENT isn't a valid HexRGB color !!!"),
+                               wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                               this);
+                  return false;
+                }
+            }
+          Fill1ColorReplacement = color;
+        }
+    }
+  return true;
+}
+
+void SimplePolygonSymbolizerDialog::UpdateFill1Page()
+{
+//
+// updating the Polygon #1 Fill page
+//
+  wxCheckBox *enableBox = (wxCheckBox *) FindWindow(ID_SYMBOLIZER_FILL1_ENABLE);
+  if (EnableFill1 == true)
+    enableBox->SetValue(true);
+  else
+    enableBox->SetValue(false);
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_FILL1_OPACITY);
+  opacityCtrl->SetValue(Fill1Opacity * 100.0);
+  if (EnableFill1 == false)
+    opacityCtrl->Enable(false);
+  else
+    opacityCtrl->Enable(true);
+  wxTextCtrl *displXCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_POLYGON1_DISPLACEMENT_X);
+  char dummy[64];
+  sprintf(dummy, "%1.2f", DisplacementX1);
+  wxString str = wxString::FromUTF8(dummy);
+  displXCtrl->SetValue(str);
+  wxTextCtrl *displYCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_POLYGON1_DISPLACEMENT_Y);
+  sprintf(dummy, "%1.2f", DisplacementY1);
+  str = wxString::FromUTF8(dummy);
+  displYCtrl->SetValue(str);
+  wxTextCtrl *perpCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_POLYGON1_PERPENDICULAR);
+  sprintf(dummy, "%1.2f", PerpendicularOffset1);
+  str = wxString::FromUTF8(dummy);
+  perpCtrl->SetValue(str);
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_FILL1_TYPE);
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL1_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL1_PICKER_HEX);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_FILL1_PICKER_BTN);
+  wxCheckBox *enableReplacement =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_FILL1_ENABLE_REPLACEMENT);
+  wxTextCtrl *replacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL1_REPLACEMENT);
+  wxTextCtrl *sampleReplacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL1_REPLACEMENT_HEX);
+  if (EnableFill1 == false)
+    {
+      typeBox->Enable(false);
+      colorCtrl->Enable(false);
+      sampleCtrl->Enable(false);
+      pick->Enable(false);
+      GridCtrl1->Enable(false);
+      enableReplacement->Enable(false);
+      replacementCtrl->Enable(false);
+  } else if (HasGraphicFill1 == false)
+    {
+      typeBox->SetSelection(0);
+      typeBox->Enable(true);
+      colorCtrl->Enable(true);
+      sampleCtrl->Enable(true);
+      pick->Enable(true);
+      GridCtrl1->Enable(false);
+      GridCtrl1->ClearSelection();
+      enableReplacement->Enable(false);
+      replacementCtrl->Enable(false);
+      wxColour color = wxNullColour;
+      ColorMapEntry::GetWxColor(Fill1Color, color);
+      if (color.IsOk() == true)
+        {
+          char hex[16];
+          sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                  color.Blue());
+          wxString str = wxString::FromUTF8(hex);
+          colorCtrl->SetValue(str);
+        }
+  } else
+    {
+      typeBox->SetSelection(1);
+      typeBox->Enable(true);
+      colorCtrl->Enable(false);
+      sampleCtrl->Enable(false);
+      pick->Enable(false);
+      GridCtrl1->Enable(true);
+      int sel = List->FindByXLinkHref(Fill1XLinkHref);
+      if (sel >= 0)
+        GridCtrl1->SelectRow(sel);
+      enableReplacement->Enable(true);
+      if (EnableFill1Replacement == true)
+        {
+          wxColour color = wxNullColour;
+          ColorMapEntry::GetWxColor(Fill1ColorReplacement, color);
+          if (color.IsOk() == true)
+            {
+              char hex[16];
+              sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                      color.Blue());
+              wxString str = wxString::FromUTF8(hex);
+              replacementCtrl->SetValue(str);
+              replacementCtrl->Enable(true);
+          } else
+            replacementCtrl->Enable(false);
+        }
+    }
+}
+
+bool SimplePolygonSymbolizerDialog::DoParseDashArray(wxString & str, int which)
+{
+//
+// attempting to parse a Stroke DashArray string
+//
+  if (which == 0)
+    {
+      Stroke1DashCount = 0;
+      if (Stroke1DashArray != NULL)
+        delete[]Stroke1DashArray;
+      Stroke1DashArray = NULL;
+    }
+  if (which == 1)
+    {
+      Stroke2DashCount = 0;
+      if (Stroke2DashArray != NULL)
+        delete[]Stroke2DashArray;
+      Stroke2DashArray = NULL;
+    }
+  if (str.Len() == 0)
+    return true;
+  int count = 0;
+  double interval;
+  wxStringTokenizer tkz(str, wxT(","));
+  while (tkz.HasMoreTokens())
+    {
+      wxString token = tkz.GetNextToken();
+      if (token.ToDouble(&interval) != true)
+        return false;
+      if (interval <= 0.0)
+        return false;
+      count++;
+    }
+  if (count == 0)
+    return true;
+  double *array;
+  if (which == 0)
+    {
+      Stroke1DashCount = count;
+      Stroke1DashArray = new double[Stroke1DashCount];
+      array = Stroke1DashArray;
+    }
+  if (which == 1)
+    {
+      Stroke2DashCount = count;
+      Stroke2DashArray = new double[Stroke2DashCount];
+      array = Stroke2DashArray;
+    }
+  count = 0;
+  wxStringTokenizer tkz2(str, wxT(","));
+  while (tkz2.HasMoreTokens())
+    {
+      wxString token = tkz2.GetNextToken();
+      token.ToDouble(&interval);
+      *(array + count++) = interval;
+    }
+  return true;
+}
+
+void SimplePolygonSymbolizerDialog::NormalizedDashArray(wxString & str,
+                                                        int which,
+                                                        char delimiter)
+{
+//
+// creating a normalized DashArray string
+//
+  int count;
+  double *array;
+  if (which == 0)
+    {
+      count = Stroke1DashCount;
+      array = Stroke1DashArray;
+    }
+  if (which == 1)
+    {
+      count = Stroke2DashCount;
+      array = Stroke2DashArray;
+    }
+  str = wxT("");
+  if (count == 0)
+    return;
+  for (int i = 0; i < count; i++)
+    {
+      char dummy[64];
+      if (i == 0)
+        sprintf(dummy, "%1.2f", *(array + i));
+      else if (delimiter == ' ')
+        sprintf(dummy, " %1.2f", *(array + i));
+      else
+        sprintf(dummy, "%c %1.2f", delimiter, *(array + i));
+      str += wxString::FromUTF8(dummy);
+    }
+}
+
+bool SimplePolygonSymbolizerDialog::RetrieveStroke1Page(bool check)
+{
+//
+// retrieving params from the STROKE #1 page
+//
+  if (EnableStroke1 == false)
+    return true;
+  wxSlider *opacityCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_STROKE1_OPACITY);
+  Stroke1Opacity = opacityCtrl->GetValue() / 100.0;
+  if (HasGraphicStroke1 == false)
+    {
+      wxTextCtrl *colorCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_COLOR);
+      wxString color = colorCtrl->GetValue();
+      if (ColorMapEntry::IsValidColor(color) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-COLOR isn't a valid HexRGB color !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      Stroke1Color = color;
+  } else
+    {
+      int selCount = 0;
+      int selected = -1;
+      for (int i = 0; i < GridCtrl2->GetNumberRows(); i++)
+        {
+          if (GridCtrl2->IsInSelection(i, 0) == true)
+            {
+              selected = i;
+              selCount++;
+            }
+        }
+      if (selCount < 1)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("You must select an External Graphic resource !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (selCount > 1)
+        {
+          if (check == true)
+            {
+              wxString msg =
+                wxT
+                ("You must select just a single External Graphic resource !!!\n");
+              msg += wxT("Multiple selection is not supported");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                           this);
+              return false;
+            }
+        }
+      List->FindByIndex(selected, Stroke1XLinkHref, Stroke1MimeType);
+      if (EnableStroke1Replacement == true)
+        {
+          wxTextCtrl *replacementCtrl =
+            (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_REPLACEMENT);
+          wxString color = replacementCtrl->GetValue();
+          if (ColorMapEntry::IsValidColor(color) != true)
+            {
+              if (check == true)
+                {
+                  wxMessageBox(wxT
+                               ("COLOR-REPACEMENT isn't a valid HexRGB color !!!"),
+                               wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                               this);
+                  return false;
+                }
+            }
+          Stroke1ColorReplacement = color;
+        }
+    }
+  wxTextCtrl *widthCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_WIDTH);
+  wxString value = widthCtrl->GetValue();
+  if (value.ToDouble(&Stroke1Width) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-WIDTH isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (Stroke1Width <= 0.0)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-WIDTH must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *dashArrayCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_DASHARRAY);
+  value = dashArrayCtrl->GetValue();
+  if (DoParseDashArray(value, 0) == false)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-DASH-ARRAY: invalid expression !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+  } else
+    {
+      NormalizedDashArray(value, 0);
+      dashArrayCtrl->SetValue(value);
+    }
+  if (Stroke1DashCount == 0)
+    Stroke1DashOffset = 0.0;
+  else
+    {
+      wxTextCtrl *offsetCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_DASHOFFSET);
+      wxString value = offsetCtrl->GetValue();
+      if (value.ToDouble(&Stroke1DashOffset) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-DASH-OFFSET isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+    }
+  return true;
+}
+
+void SimplePolygonSymbolizerDialog::UpdateStroke1Page()
+{
+//
+// updating the STROKE #1 page
+//
+  wxCheckBox *enableBox =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE1_ENABLE);
+  if (EnableStroke1 == true)
+    enableBox->SetValue(true);
+  else
+    enableBox->SetValue(false);
+  wxSlider *opacityCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_STROKE1_OPACITY);
+  opacityCtrl->SetValue(Stroke1Opacity * 100.0);
+  if (EnableStroke1 == false)
+    opacityCtrl->Enable(false);
+  else
+    opacityCtrl->Enable(true);
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE1_TYPE);
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_PICKER_HEX);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_STROKE1_PICKER_BTN);
+  wxCheckBox *enableReplacement =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE1_ENABLE_REPLACEMENT);
+  wxTextCtrl *replacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_REPLACEMENT);
+  wxTextCtrl *sampleReplacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_REPLACEMENT_HEX);
+  if (EnableStroke1 == false)
+    {
+      typeBox->Enable(false);
+      colorCtrl->Enable(false);
+      sampleCtrl->Enable(false);
+      pick->Enable(false);
+      GridCtrl2->Enable(false);
+      enableReplacement->Enable(false);
+      replacementCtrl->Enable(false);
+  } else
+    {
+      typeBox->Enable(true);
+      if (HasGraphicStroke1 == false)
+        {
+          typeBox->SetSelection(0);
+          typeBox->Enable(true);
+          colorCtrl->Enable(true);
+          sampleCtrl->Enable(true);
+          pick->Enable(true);
+          GridCtrl2->Enable(false);
+          GridCtrl2->ClearSelection();
+          enableReplacement->Enable(false);
+          replacementCtrl->Enable(false);
+          wxColour color = wxNullColour;
+          ColorMapEntry::GetWxColor(Stroke1Color, color);
+          if (color.IsOk() == true)
+            {
+              char hex[16];
+              sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                      color.Blue());
+              wxString str = wxString::FromUTF8(hex);
+              colorCtrl->SetValue(str);
+            }
+      } else
+        {
+          typeBox->SetSelection(1);
+          typeBox->Enable(true);
+          colorCtrl->Enable(false);
+          sampleCtrl->Enable(false);
+          pick->Enable(false);
+          GridCtrl2->Enable(true);
+          int sel = List->FindByXLinkHref(Stroke1XLinkHref);
+          if (sel >= 0)
+            GridCtrl2->SelectRow(sel);
+          enableReplacement->Enable(true);
+          if (EnableStroke1Replacement == true)
+            {
+              wxColour color = wxNullColour;
+              ColorMapEntry::GetWxColor(Stroke1ColorReplacement, color);
+              if (color.IsOk() == true)
+                {
+                  char hex[16];
+                  sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                          color.Blue());
+                  wxString str = wxString::FromUTF8(hex);
+                  replacementCtrl->SetValue(str);
+                  replacementCtrl->Enable(true);
+              } else
+                replacementCtrl->Enable(false);
+            }
+        }
+    }
+  wxTextCtrl *widthCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_WIDTH);
+  char dummy[64];
+  sprintf(dummy, "%1.2f", Stroke1Width);
+  wxString str = wxString::FromUTF8(dummy);
+  widthCtrl->SetValue(str);
+  if (EnableStroke1 == false)
+    widthCtrl->Enable(false);
+  else
+    widthCtrl->Enable(true);
+  wxRadioBox *lineJoinCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE1_LINEJOIN);
+  switch (Stroke1LineJoin)
+    {
+      case RL2_PEN_JOIN_MITER:
+        lineJoinCtrl->SetSelection(0);
+        break;
+      case RL2_PEN_JOIN_BEVEL:
+        lineJoinCtrl->SetSelection(2);
+        break;
+      default:
+        lineJoinCtrl->SetSelection(1);
+        break;
+    };
+  if (EnableStroke1 == false)
+    lineJoinCtrl->Enable(false);
+  else
+    lineJoinCtrl->Enable(true);
+  wxRadioBox *lineCapCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE1_LINECAP);
+  switch (Stroke1LineCap)
+    {
+      case RL2_PEN_CAP_BUTT:
+        lineCapCtrl->SetSelection(0);
+        break;
+      case RL2_PEN_CAP_SQUARE:
+        lineCapCtrl->SetSelection(2);
+        break;
+      default:
+        lineCapCtrl->SetSelection(1);
+        break;
+    };
+  if (EnableStroke1 == false)
+    lineCapCtrl->Enable(false);
+  else
+    lineCapCtrl->Enable(true);
+  wxTextCtrl *dashArrayCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_DASHARRAY);
+  wxString value;
+  NormalizedDashArray(value, 0);
+  dashArrayCtrl->SetValue(value);
+  if (EnableStroke1 == false)
+    dashArrayCtrl->Enable(false);
+  else
+    dashArrayCtrl->Enable(true);
+  wxTextCtrl *offsetCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE1_DASHOFFSET);
+  if (Stroke1DashCount == 0)
+    offsetCtrl->SetValue(wxT("0.0"));
+  else
+    {
+      char dummy[64];
+      sprintf(dummy, "%1.2f", Stroke1DashOffset);
+      wxString str = wxString::FromUTF8(dummy);
+      offsetCtrl->SetValue(str);
+    }
+  if (EnableStroke1 == false)
+    offsetCtrl->Enable(false);
+  else
+    offsetCtrl->Enable(true);
+}
+
+bool SimplePolygonSymbolizerDialog::RetrieveFill2Page(bool check)
+{
+//
+// retrieving params from the Polygon #2 Fill page
+//
+  if (EnablePolygon2 == false)
+    return true;
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_FILL2_OPACITY);
+  Fill2Opacity = opacityCtrl->GetValue() / 100.0;
+  wxTextCtrl *displXCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_POLYGON2_DISPLACEMENT_X);
+  wxString value = displXCtrl->GetValue();
+  if (value.ToDouble(&DisplacementX2) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("DISPLACEMENT-X isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *displYCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_POLYGON2_DISPLACEMENT_Y);
+  value = displYCtrl->GetValue();
+  if (value.ToDouble(&DisplacementY2) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("DISPLACEMENT-Y isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *perpCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_POLYGON2_PERPENDICULAR);
+  value = perpCtrl->GetValue();
+  if (value.ToDouble(&PerpendicularOffset2) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("PERPENDICULAR-OFFSET isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (HasGraphicFill2 == false)
+    {
+      wxTextCtrl *colorCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL2_COLOR);
+      wxString color = colorCtrl->GetValue();
+      if (ColorMapEntry::IsValidColor(color) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("FILL-COLOR isn't a valid HexRGB color !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      Fill2Color = color;
+  } else
+    {
+      int selCount = 0;
+      int selected = -1;
+      for (int i = 0; i < GridCtrl3->GetNumberRows(); i++)
+        {
+          if (GridCtrl3->IsInSelection(i, 0) == true)
+            {
+              selected = i;
+              selCount++;
+            }
+        }
+      if (selCount < 1)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("You must select an External Graphic resource !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (selCount > 1)
+        {
+          if (check == true)
+            {
+              wxString msg =
+                wxT
+                ("You must select just a single External Graphic resource !!!\n");
+              msg += wxT("Multiple selection is not supported");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                           this);
+              return false;
+            }
+        }
+      List->FindByIndex(selected, Fill2XLinkHref, Fill2MimeType);
+      if (EnableFill2Replacement == true)
+        {
+          wxTextCtrl *replacementCtrl =
+            (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL2_REPLACEMENT);
+          wxString color = replacementCtrl->GetValue();
+          if (ColorMapEntry::IsValidColor(color) != true)
+            {
+              if (check == true)
+                {
+                  wxMessageBox(wxT
+                               ("COLOR-REPACEMENT isn't a valid HexRGB color !!!"),
+                               wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                               this);
+                  return false;
+                }
+            }
+          Fill2ColorReplacement = color;
+        }
+    }
+  return true;
+}
+
+void SimplePolygonSymbolizerDialog::UpdateFill2Page()
+{
+//
+// updating the Polygon #2 Fill page
+//
+  wxCheckBox *polygonBox =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_POLYGON2_ENABLE);
+  if (EnablePolygon2 == true)
+    polygonBox->SetValue(true);
+  else
+    polygonBox->SetValue(false);
+  if (EnablePolygon2 == false)
+    EnableFill2 = false;
+  wxCheckBox *enableBox = (wxCheckBox *) FindWindow(ID_SYMBOLIZER_FILL2_ENABLE);
+  if (EnableFill2 == true)
+    enableBox->SetValue(true);
+  else
+    enableBox->SetValue(false);
+  if (EnablePolygon2 == true)
+    enableBox->Enable(true);
+  else
+    enableBox->Enable(false);
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_FILL2_OPACITY);
+  opacityCtrl->SetValue(Fill2Opacity * 100.0);
+  if (EnablePolygon2 == true)
+    {
+      if (EnableFill2 == false)
+        opacityCtrl->Enable(false);
+      else
+        opacityCtrl->Enable(true);
+  } else
+    opacityCtrl->Enable(false);
+  wxTextCtrl *displXCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_POLYGON2_DISPLACEMENT_X);
+  char dummy[64];
+  sprintf(dummy, "%1.2f", DisplacementX2);
+  wxString str = wxString::FromUTF8(dummy);
+  displXCtrl->SetValue(str);
+  if (EnablePolygon2 == true)
+    displXCtrl->Enable(true);
+  else
+    displXCtrl->Enable(false);
+  wxTextCtrl *displYCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_POLYGON2_DISPLACEMENT_Y);
+  sprintf(dummy, "%1.2f", DisplacementY2);
+  str = wxString::FromUTF8(dummy);
+  displYCtrl->SetValue(str);
+  if (EnablePolygon2 == true)
+    displYCtrl->Enable(true);
+  else
+    displYCtrl->Enable(false);
+  wxTextCtrl *perpCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_POLYGON2_PERPENDICULAR);
+  sprintf(dummy, "%1.2f", PerpendicularOffset2);
+  str = wxString::FromUTF8(dummy);
+  perpCtrl->SetValue(str);
+  if (EnablePolygon2 == true)
+    perpCtrl->Enable(true);
+  else
+    perpCtrl->Enable(false);
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_FILL2_TYPE);
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL2_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL2_PICKER_HEX);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_FILL2_PICKER_BTN);
+  wxCheckBox *enableReplacement =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_FILL2_ENABLE_REPLACEMENT);
+  wxTextCtrl *replacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL2_REPLACEMENT);
+  wxTextCtrl *sampleReplacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL2_REPLACEMENT_HEX);
+  if (EnablePolygon2 == false)
+    {
+      typeBox->Enable(false);
+      colorCtrl->Enable(false);
+      sampleCtrl->Enable(false);
+      pick->Enable(false);
+      GridCtrl3->Enable(false);
+  } else if (EnableFill2 == false)
+    {
+      typeBox->Enable(false);
+      colorCtrl->Enable(false);
+      sampleCtrl->Enable(false);
+      pick->Enable(false);
+      GridCtrl3->Enable(false);
+      enableReplacement->Enable(false);
+      replacementCtrl->Enable(false);
+  } else if (HasGraphicFill2 == false)
+    {
+      typeBox->SetSelection(0);
+      typeBox->Enable(true);
+      colorCtrl->Enable(true);
+      sampleCtrl->Enable(true);
+      pick->Enable(true);
+      GridCtrl1->Enable(false);
+      GridCtrl1->ClearSelection();
+      enableReplacement->Enable(false);
+      replacementCtrl->Enable(false);
+      wxColour color = wxNullColour;
+      ColorMapEntry::GetWxColor(Fill2Color, color);
+      if (color.IsOk() == true)
+        {
+          char hex[16];
+          sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                  color.Blue());
+          wxString str = wxString::FromUTF8(hex);
+          colorCtrl->SetValue(str);
+        }
+  } else
+    {
+      typeBox->SetSelection(1);
+      typeBox->Enable(true);
+      colorCtrl->Enable(false);
+      sampleCtrl->Enable(false);
+      pick->Enable(false);
+      GridCtrl3->Enable(true);
+      int sel = List->FindByXLinkHref(Fill2XLinkHref);
+      if (sel >= 0)
+        GridCtrl3->SelectRow(sel);
+      enableReplacement->Enable(true);
+      if (EnableFill2Replacement == true)
+        {
+          wxColour color = wxNullColour;
+          ColorMapEntry::GetWxColor(Fill2ColorReplacement, color);
+          if (color.IsOk() == true)
+            {
+              char hex[16];
+              sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                      color.Blue());
+              wxString str = wxString::FromUTF8(hex);
+              replacementCtrl->SetValue(str);
+              replacementCtrl->Enable(true);
+          } else
+            replacementCtrl->Enable(false);
+        }
+    }
+}
+
+bool SimplePolygonSymbolizerDialog::RetrieveStroke2Page(bool check)
+{
+//
+// retrieving params from the STROKE #2 page
+//
+  if (EnableStroke2 == false || EnablePolygon2 == false)
+    return true;
+  wxSlider *opacityCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_STROKE2_OPACITY);
+  Stroke2Opacity = opacityCtrl->GetValue() / 100.0;
+  if (HasGraphicStroke2 == false)
+    {
+      wxTextCtrl *colorCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_COLOR);
+      wxString color = colorCtrl->GetValue();
+      if (ColorMapEntry::IsValidColor(color) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-COLOR isn't a valid HexRGB color !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      Stroke2Color = color;
+  } else
+    {
+      int selCount = 0;
+      int selected = -1;
+      for (int i = 0; i < GridCtrl4->GetNumberRows(); i++)
+        {
+          if (GridCtrl4->IsInSelection(i, 0) == true)
+            {
+              selected = i;
+              selCount++;
+            }
+        }
+      if (selCount < 1)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("You must select an External Graphic resource !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (selCount > 1)
+        {
+          if (check == true)
+            {
+              wxString msg =
+                wxT
+                ("You must select just a single External Graphic resource !!!\n");
+              msg += wxT("Multiple selection is not supported");
+              wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                           this);
+              return false;
+            }
+        }
+      List->FindByIndex(selected, Stroke2XLinkHref, Stroke2MimeType);
+      if (EnableStroke2Replacement == true)
+        {
+          wxTextCtrl *replacementCtrl =
+            (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_REPLACEMENT);
+          wxString color = replacementCtrl->GetValue();
+          if (ColorMapEntry::IsValidColor(color) != true)
+            {
+              if (check == true)
+                {
+                  wxMessageBox(wxT
+                               ("COLOR-REPACEMENT isn't a valid HexRGB color !!!"),
+                               wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                               this);
+                  return false;
+                }
+            }
+          Stroke2ColorReplacement = color;
+        }
+    }
+  wxTextCtrl *widthCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_WIDTH);
+  wxString value = widthCtrl->GetValue();
+  if (value.ToDouble(&Stroke2Width) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-WIDTH isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (Stroke2Width <= 0.0)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-WIDTH must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *dashArrayCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_DASHARRAY);
+  value = dashArrayCtrl->GetValue();
+  if (DoParseDashArray(value, 1) == false)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("STROKE-DASH-ARRAY: invalid expression !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+  } else
+    {
+      NormalizedDashArray(value, 1);
+      dashArrayCtrl->SetValue(value);
+    }
+  if (Stroke2DashCount == 0)
+    Stroke2DashOffset = 0.0;
+  else
+    {
+      wxTextCtrl *offsetCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_DASHOFFSET);
+      wxString value = offsetCtrl->GetValue();
+      if (value.ToDouble(&Stroke2DashOffset) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-DASH-OFFSET isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+    }
+  return true;
+}
+
+void SimplePolygonSymbolizerDialog::UpdateStroke2Page()
+{
+//
+// updating the STROKE #1 page
+//
+  if (EnablePolygon2 == false)
+    EnableStroke2 = false;
+  wxCheckBox *enableBox =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE2_ENABLE);
+  if (EnableStroke2 == true)
+    enableBox->SetValue(true);
+  else
+    enableBox->SetValue(false);
+  if (EnablePolygon2 == true)
+    enableBox->Enable(true);
+  else
+    enableBox->Enable(false);
+  wxSlider *opacityCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_STROKE2_OPACITY);
+  opacityCtrl->SetValue(Stroke2Opacity * 100.0);
+  if (EnableStroke2 == false)
+    opacityCtrl->Enable(false);
+  else
+    opacityCtrl->Enable(true);
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE2_TYPE);
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_PICKER_HEX);
+  wxButton *pick = (wxButton *) FindWindow(ID_SYMBOLIZER_STROKE2_PICKER_BTN);
+  wxCheckBox *enableReplacement =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE2_ENABLE_REPLACEMENT);
+  wxTextCtrl *replacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_REPLACEMENT);
+  wxTextCtrl *sampleReplacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_REPLACEMENT_HEX);
+  if (EnableStroke2 == false)
+    {
+      typeBox->Enable(false);
+      colorCtrl->Enable(false);
+      sampleCtrl->Enable(false);
+      pick->Enable(false);
+      GridCtrl4->Enable(false);
+      enableReplacement->Enable(false);
+      replacementCtrl->Enable(false);
+  } else
+    {
+      typeBox->Enable(true);
+      if (HasGraphicStroke2 == false)
+        {
+          typeBox->SetSelection(0);
+          typeBox->Enable(true);
+          colorCtrl->Enable(true);
+          sampleCtrl->Enable(true);
+          pick->Enable(true);
+          GridCtrl4->Enable(false);
+          GridCtrl4->ClearSelection();
+          enableReplacement->Enable(false);
+          replacementCtrl->Enable(false);
+          wxColour color = wxNullColour;
+          ColorMapEntry::GetWxColor(Stroke2Color, color);
+          if (color.IsOk() == true)
+            {
+              char hex[16];
+              sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                      color.Blue());
+              wxString str = wxString::FromUTF8(hex);
+              colorCtrl->SetValue(str);
+            }
+      } else
+        {
+          typeBox->SetSelection(1);
+          typeBox->Enable(true);
+          colorCtrl->Enable(false);
+          sampleCtrl->Enable(false);
+          pick->Enable(false);
+          GridCtrl4->Enable(true);
+          int sel = List->FindByXLinkHref(Stroke2XLinkHref);
+          if (sel >= 0)
+            GridCtrl4->SelectRow(sel);
+          enableReplacement->Enable(true);
+          if (EnableStroke2Replacement == true)
+            {
+              wxColour color = wxNullColour;
+              ColorMapEntry::GetWxColor(Stroke2ColorReplacement, color);
+              if (color.IsOk() == true)
+                {
+                  char hex[16];
+                  sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                          color.Blue());
+                  wxString str = wxString::FromUTF8(hex);
+                  replacementCtrl->SetValue(str);
+                  replacementCtrl->Enable(true);
+              } else
+                replacementCtrl->Enable(false);
+            }
+        }
+    }
+  wxTextCtrl *widthCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_WIDTH);
+  char dummy[64];
+  sprintf(dummy, "%1.2f", Stroke2Width);
+  wxString str = wxString::FromUTF8(dummy);
+  widthCtrl->SetValue(str);
+  if (EnableStroke2 == false)
+    widthCtrl->Enable(false);
+  else
+    widthCtrl->Enable(true);
+  wxRadioBox *lineJoinCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE2_LINEJOIN);
+  switch (Stroke2LineJoin)
+    {
+      case RL2_PEN_JOIN_MITER:
+        lineJoinCtrl->SetSelection(0);
+        break;
+      case RL2_PEN_JOIN_BEVEL:
+        lineJoinCtrl->SetSelection(2);
+        break;
+      default:
+        lineJoinCtrl->SetSelection(1);
+        break;
+    };
+  if (EnableStroke2 == false)
+    lineJoinCtrl->Enable(false);
+  else
+    lineJoinCtrl->Enable(true);
+  wxRadioBox *lineCapCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE2_LINECAP);
+  switch (Stroke2LineCap)
+    {
+      case RL2_PEN_CAP_BUTT:
+        lineCapCtrl->SetSelection(0);
+        break;
+      case RL2_PEN_CAP_SQUARE:
+        lineCapCtrl->SetSelection(2);
+        break;
+      default:
+        lineCapCtrl->SetSelection(1);
+        break;
+    };
+  if (EnableStroke2 == false)
+    lineCapCtrl->Enable(false);
+  else
+    lineCapCtrl->Enable(true);
+  wxTextCtrl *dashArrayCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_DASHARRAY);
+  wxString value;
+  NormalizedDashArray(value, 1);
+  dashArrayCtrl->SetValue(value);
+  if (EnableStroke2 == false)
+    dashArrayCtrl->Enable(false);
+  else
+    dashArrayCtrl->Enable(true);
+  wxTextCtrl *offsetCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE2_DASHOFFSET);
+  if (Stroke2DashCount == 0)
+    offsetCtrl->SetValue(wxT("0.0"));
+  else
+    {
+      char dummy[64];
+      sprintf(dummy, "%1.2f", Stroke2DashOffset);
+      wxString str = wxString::FromUTF8(dummy);
+      offsetCtrl->SetValue(str);
+    }
+  if (EnableStroke2 == false)
+    offsetCtrl->Enable(false);
+  else
+    offsetCtrl->Enable(true);
+}
+
+bool SimplePolygonSymbolizerDialog::RetrievePreviewPage()
+{
+//
+// retrieving params from the PREVIEW page
+//
+  return true;
+}
+
+void SimplePolygonSymbolizerDialog::PreparePolygonPath(void *xctx,
+                                                       double
+                                                       perpendicular_offset,
+                                                       double displacement_x,
+                                                       double displacement_y)
+{
+// Visual Preview
+
+// exterior ring
+  gaiaDynamicLinePtr dyn = gaiaAllocDynamicLine();
+  gaiaAppendPointToDynamicLine(dyn, 190.0, 40.0);
+  double pi = 3.14159265359;
+  for (double rads = (2.0 * pi) - (pi / 2.0); rads >= 0.1; rads -= 0.666666)
+    {
+      double x = 135.0 + (115.0 * cos(rads));
+      double y = 150.0 + (115.0 * sin(rads));
+      gaiaAppendPointToDynamicLine(dyn, x, y);
+    }
+  gaiaAppendPointToDynamicLine(dyn, 230.0, 200.0);
+  gaiaAppendPointToDynamicLine(dyn, 250.0, 200.0);
+  gaiaAppendPointToDynamicLine(dyn, 270.0, 220.0);
+  gaiaAppendPointToDynamicLine(dyn, 290.0, 200.0);
+  gaiaAppendPointToDynamicLine(dyn, 310.0, 220.0);
+  gaiaAppendPointToDynamicLine(dyn, 330.0, 200.0);
+  gaiaAppendPointToDynamicLine(dyn, 350.0, 220.0);
+  gaiaAppendPointToDynamicLine(dyn, 350.0, 260.0);
+  for (double rads = (pi * 2.0) + (pi / 2.0); rads >= pi + (pi / 4.0);
+       rads -= 0.1)
+    {
+      double x = 365.0 + (115.0 * cos(rads));
+      double y = 150.0 + (115.0 * sin(rads));
+      gaiaAppendPointToDynamicLine(dyn, x, y);
+    }
+  gaiaAppendPointToDynamicLine(dyn, 250.0, 40.0);
+  gaiaAppendPointToDynamicLine(dyn, 250.0, 80.0);
+  gaiaAppendPointToDynamicLine(dyn, 200.0, 80.0);
+
+  int points = 0;
+  gaiaPointPtr pt = dyn->First;
+  while (pt != NULL)
+    {
+      // counting how many Points are there
+      points++;
+      pt = pt->Next;
+    }
+  gaiaGeomCollPtr geom = gaiaAllocGeomColl();
+  gaiaPolygonPtr pg = gaiaAddPolygonToGeomColl(geom, points + 1, 1);
+  gaiaRingPtr rng = pg->Exterior;
+  int iv = 0;
+  pt = dyn->First;
+  while (pt != NULL)
+    {
+      // preparing the Exterior Ring
+      gaiaSetPoint(rng->Coords, iv, pt->X, pt->Y);
+      iv++;
+      pt = pt->Next;
+    }
+  gaiaSetPoint(rng->Coords, points, dyn->First->X, dyn->Last->Y);
+  gaiaFreeDynamicLine(dyn);
+
+// interior ring
+  dyn = gaiaAllocDynamicLine();
+  gaiaAppendPointToDynamicLine(dyn, 350.0, 160.0);
+  gaiaAppendPointToDynamicLine(dyn, 380.0, 160.0);
+  gaiaAppendPointToDynamicLine(dyn, 380.0, 130.0);
+  for (double rads = (pi * 2.0) + (pi / 4.0); rads >= pi + (pi / 4.0);
+       rads -= 0.1)
+    {
+      double x = 370.0 + (55.0 * cos(rads));
+      double y = 140.0 + (55.0 * sin(rads));
+      gaiaAppendPointToDynamicLine(dyn, x, y);
+    }
+  points = 0;
+  pt = dyn->First;
+  while (pt != NULL)
+    {
+      // counting how many Points are there
+      points++;
+      pt = pt->Next;
+    }
+  rng = gaiaAddInteriorRing(pg, 0, points + 1);
+  iv = 0;
+  pt = dyn->First;
+  while (pt != NULL)
+    {
+      // preparing the Interior Ring
+      gaiaSetPoint(rng->Coords, iv, pt->X, pt->Y);
+      iv++;
+      pt = pt->Next;
+    }
+  gaiaSetPoint(rng->Coords, points, dyn->First->X, dyn->Last->Y);
+  gaiaFreeDynamicLine(dyn);
+
+  gaiaGeomCollPtr geom2;
+  if (perpendicular_offset != 0.0)
+    {
+      // buffering
+      geom2 =
+        gaiaGeomCollBuffer_r(MainFrame->GetSpliteInternalCache(), geom,
+                             perpendicular_offset, 16);
+      gaiaFreeGeomColl(geom);
+  } else
+    {
+      // unchanged
+      geom2 = geom;
+    }
+  if (displacement_x != 0.0 || displacement_y != 0.0)
+    {
+      // displacing
+      gaiaShiftCoords(geom2, displacement_x, displacement_y);
+    }
+// preparing the Stroke Path
+  pg = geom2->FirstPolygon;
+  rng = pg->Exterior;
+  rl2GraphicsContextPtr ctx = (rl2GraphicsContextPtr) xctx;
+  for (iv = 0; iv < rng->Points; iv++)
+    {
+      double x;
+      double y;
+      gaiaGetPoint(rng->Coords, iv, &x, &y);
+      if (iv == 0)
+        rl2_graph_move_to_point(ctx, x, y);
+      else
+        rl2_graph_add_line_to_path(ctx, x, y);
+    }
+  rl2_graph_close_subpath(ctx);
+  rng = pg->Interiors;
+  for (iv = 0; iv < rng->Points; iv++)
+    {
+      double x;
+      double y;
+      gaiaGetPoint(rng->Coords, iv, &x, &y);
+      if (iv == 0)
+        rl2_graph_move_to_point(ctx, x, y);
+      else
+        rl2_graph_add_line_to_path(ctx, x, y);
+    }
+  rl2_graph_close_subpath(ctx);
+  gaiaFreeGeomColl(geom2);
+}
+
+void SimplePolygonSymbolizerDialog::UpdatePreviewPage()
+{
+//
+// updating the PREVIEW page
+//
+  rl2GraphicsPatternPtr pattern1 = NULL;
+  rl2GraphicsPatternPtr pattern2 = NULL;
+  rl2GraphicsPatternPtr pattern3 = NULL;
+  rl2GraphicsPatternPtr pattern4 = NULL;
+  wxRadioBox *backCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_BACKGROUND);
+  switch (PreviewBackground)
+    {
+      case GUI_PREVIEW_BACKGROUND_WHITE:
+        backCtrl->SetSelection(1);
+        break;
+      case GUI_PREVIEW_BACKGROUND_BLACK:
+        backCtrl->SetSelection(2);
+        break;
+      default:
+        backCtrl->SetSelection(0);
+        break;
+    };
+  rl2GraphicsContextPtr ctx = NULL;
+  ctx = rl2_graph_create_context(500, 300);
+  if (ctx == NULL)
+    return;
+// transparent background initialization
+  rl2_graph_set_brush(ctx, 255, 255, 255, 0);
+  rl2_graph_draw_rectangle(ctx, -1, -1, 501, 301);
+
+  if (EnableFill1 == true || EnableStroke1 == true)
+    {
+      if (EnableFill1 == true)
+        {
+          if (HasGraphicFill1 == false)
+            {
+              // preparing a Color-based Brush
+              double aleph = 255.0 * Fill1Opacity;
+              if (aleph < 0.0)
+                aleph = 0.0;
+              if (aleph > 255.0)
+                aleph = 255.0;
+              unsigned char alpha = aleph;
+              wxColour color = wxNullColour;
+              ColorMapEntry::GetWxColor(Fill1Color, color);
+              rl2_graph_set_brush(ctx, color.Red(), color.Green(), color.Blue(),
+                                  alpha);
+          } else
+            {
+              // preparing a Pattern-based Brush
+              pattern1 =
+                rl2_create_pattern_from_external_graphic(MainFrame->GetSqlite(),
+                                                         Fill1XLinkHref.ToUTF8
+                                                         (), 1);
+              if (pattern1 != NULL)
+                {
+                  if (EnableFill1Replacement)
+                    {
+                      // attempting to recolor the External Graphic resource
+                      wxColour color = wxNullColour;
+                      ColorMapEntry::GetWxColor(Fill1ColorReplacement, color);
+                      rl2_graph_pattern_recolor(pattern1, color.Red(),
+                                                color.Green(), color.Blue());
+                    }
+                  if (Fill1Opacity < 1.0)
+                    {
+                      // setting up the required transparency
+                      double aleph = 255.0 * Fill1Opacity;
+                      if (aleph < 0.0)
+                        aleph = 0.0;
+                      if (aleph > 255.0)
+                        aleph = 255.0;
+                      unsigned char alpha = aleph;
+                      rl2_graph_pattern_transparency(pattern1, alpha);
+                    }
+                  rl2_graph_set_pattern_brush(ctx, pattern1);
+              } else
+                {
+                  // invalid Pattern: defaulting to a Gray brush
+                  rl2_graph_set_brush(ctx, 128, 128, 128, 255);
+                }
+            }
+        }
+      if (EnableStroke1 == true)
+        {
+          if (HasGraphicStroke1 == false)
+            {
+              // preparing a Color-based Pen
+              double aleph = 255.0 * Stroke1Opacity;
+              if (aleph < 0.0)
+                aleph = 0.0;
+              if (aleph > 255.0)
+                aleph = 255.0;
+              unsigned char alpha = aleph;
+              wxColour color = wxNullColour;
+              ColorMapEntry::GetWxColor(Stroke1Color, color);
+              if (Stroke1DashCount == 0)
+                rl2_graph_set_solid_pen(ctx, color.Red(), color.Green(),
+                                        color.Blue(), alpha, Stroke1Width,
+                                        Stroke1LineCap, Stroke1LineJoin);
+              else
+                rl2_graph_set_dashed_pen(ctx, color.Red(), color.Green(),
+                                         color.Blue(), alpha, Stroke1Width,
+                                         Stroke1LineCap, Stroke1LineJoin,
+                                         Stroke1DashCount, Stroke1DashArray,
+                                         Stroke1DashOffset);
+          } else
+            {
+              // preparing a Pattern-based Pen
+              pattern2 =
+                rl2_create_pattern_from_external_graphic(MainFrame->GetSqlite(),
+                                                         Stroke1XLinkHref.ToUTF8
+                                                         (), 1);
+              if (pattern2 != NULL)
+                {
+                  if (EnableStroke1Replacement)
+                    {
+                      // attempting to recolor the External Graphic resource
+                      wxColour color = wxNullColour;
+                      ColorMapEntry::GetWxColor(Stroke1ColorReplacement, color);
+                      rl2_graph_pattern_recolor(pattern2, color.Red(),
+                                                color.Green(), color.Blue());
+                    }
+                  if (Stroke1Opacity < 1.0)
+                    {
+                      // setting up the required transparency
+                      double aleph = 255.0 * Stroke1Opacity;
+                      if (aleph < 0.0)
+                        aleph = 0.0;
+                      if (aleph > 255.0)
+                        aleph = 255.0;
+                      unsigned char alpha = aleph;
+                      rl2_graph_pattern_transparency(pattern2, alpha);
+                    }
+                  if (Stroke1DashCount == 0)
+                    rl2_graph_set_pattern_solid_pen(ctx, pattern2, Stroke1Width,
+                                                    Stroke1LineCap,
+                                                    Stroke1LineJoin);
+                  else
+                    rl2_graph_set_pattern_dashed_pen(ctx, pattern2,
+                                                     Stroke1Width,
+                                                     Stroke1LineCap,
+                                                     Stroke1LineJoin,
+                                                     Stroke1DashCount,
+                                                     Stroke1DashArray,
+                                                     Stroke1DashOffset);
+              } else
+                {
+                  // invalid Pattern: defaulting to a black Pen
+                  if (Stroke1DashCount == 0)
+                    rl2_graph_set_solid_pen(ctx, 0, 0, 0, 255, Stroke1Width,
+                                            Stroke1LineCap, Stroke1LineJoin);
+                  else
+                    rl2_graph_set_dashed_pen(ctx, 0, 0, 0, 255, Stroke1Width,
+                                             Stroke1LineCap, Stroke1LineJoin,
+                                             Stroke1DashCount, Stroke1DashArray,
+                                             Stroke1DashOffset);
+                }
+            }
+        }
+      PreparePolygonPath(ctx, PerpendicularOffset1, DisplacementX1,
+                         DisplacementY1);
+      if (EnableFill1 == true && EnableStroke1)
+        {
+          // applying both Fill and Stroke
+          rl2_graph_fill_path(ctx, RL2_PRESERVE_PATH);
+          rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
+      } else if (EnableFill1 == true)
+        {
+          // applying Fill only
+          rl2_graph_fill_path(ctx, RL2_CLEAR_PATH);
+      } else if (EnableStroke1 == true)
+        {
+          // applying Stroke only
+          rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
+        }
+    }
+
+  if (EnablePolygon2 == true && (EnableFill2 == true || EnableStroke2 == true))
+    {
+      if (EnableFill2 == true)
+        {
+          if (HasGraphicFill2 == false)
+            {
+              // preparing a Color-based Brush
+              double aleph = 255.0 * Fill2Opacity;
+              if (aleph < 0.0)
+                aleph = 0.0;
+              if (aleph > 255.0)
+                aleph = 255.0;
+              unsigned char alpha = aleph;
+              wxColour color = wxNullColour;
+              ColorMapEntry::GetWxColor(Fill2Color, color);
+              rl2_graph_set_brush(ctx, color.Red(), color.Green(), color.Blue(),
+                                  alpha);
+          } else
+            {
+              // preparing a Pattern-based Brush
+              pattern3 =
+                rl2_create_pattern_from_external_graphic(MainFrame->GetSqlite(),
+                                                         Fill2XLinkHref.ToUTF8
+                                                         (), 1);
+              if (pattern3 != NULL)
+                {
+                  if (EnableFill2Replacement)
+                    {
+                      // attempting to recolor the External Graphic resource
+                      wxColour color = wxNullColour;
+                      ColorMapEntry::GetWxColor(Fill2ColorReplacement, color);
+                      rl2_graph_pattern_recolor(pattern3, color.Red(),
+                                                color.Green(), color.Blue());
+                    }
+                  if (Fill2Opacity < 1.0)
+                    {
+                      // setting up the required transparency
+                      double aleph = 255.0 * Fill2Opacity;
+                      if (aleph < 0.0)
+                        aleph = 0.0;
+                      if (aleph > 255.0)
+                        aleph = 255.0;
+                      unsigned char alpha = aleph;
+                      rl2_graph_pattern_transparency(pattern3, alpha);
+                    }
+                  rl2_graph_set_pattern_brush(ctx, pattern3);
+              } else
+                {
+                  // invalid Pattern: defaulting to a Gray brush
+                  rl2_graph_set_brush(ctx, 128, 128, 128, 255);
+                }
+            }
+        }
+      if (EnableStroke2 == true)
+        {
+          if (HasGraphicStroke2 == false)
+            {
+              // preparing a Color-based Pen
+              double aleph = 255.0 * Stroke2Opacity;
+              if (aleph < 0.0)
+                aleph = 0.0;
+              if (aleph > 255.0)
+                aleph = 255.0;
+              unsigned char alpha = aleph;
+              wxColour color = wxNullColour;
+              ColorMapEntry::GetWxColor(Stroke2Color, color);
+              if (Stroke2DashCount == 0)
+                rl2_graph_set_solid_pen(ctx, color.Red(), color.Green(),
+                                        color.Blue(), alpha, Stroke2Width,
+                                        Stroke2LineCap, Stroke2LineJoin);
+              else
+                rl2_graph_set_dashed_pen(ctx, color.Red(), color.Green(),
+                                         color.Blue(), alpha, Stroke2Width,
+                                         Stroke2LineCap, Stroke2LineJoin,
+                                         Stroke2DashCount, Stroke2DashArray,
+                                         Stroke2DashOffset);
+          } else
+            {
+              // preparing a Pattern-based Pen
+              pattern4 =
+                rl2_create_pattern_from_external_graphic(MainFrame->GetSqlite(),
+                                                         Stroke2XLinkHref.ToUTF8
+                                                         (), 1);
+              if (pattern4 != NULL)
+                {
+                  if (EnableStroke2Replacement)
+                    {
+                      // attempting to recolor the External Graphic resource
+                      wxColour color = wxNullColour;
+                      ColorMapEntry::GetWxColor(Stroke2ColorReplacement, color);
+                      rl2_graph_pattern_recolor(pattern4, color.Red(),
+                                                color.Green(), color.Blue());
+                    }
+                  if (Stroke2Opacity < 1.0)
+                    {
+                      // setting up the required transparency
+                      double aleph = 255.0 * Stroke2Opacity;
+                      if (aleph < 0.0)
+                        aleph = 0.0;
+                      if (aleph > 255.0)
+                        aleph = 255.0;
+                      unsigned char alpha = aleph;
+                      rl2_graph_pattern_transparency(pattern4, alpha);
+                    }
+                  if (Stroke2DashCount == 0)
+                    rl2_graph_set_pattern_solid_pen(ctx, pattern4, Stroke2Width,
+                                                    Stroke2LineCap,
+                                                    Stroke2LineJoin);
+                  else
+                    rl2_graph_set_pattern_dashed_pen(ctx, pattern4,
+                                                     Stroke2Width,
+                                                     Stroke2LineCap,
+                                                     Stroke2LineJoin,
+                                                     Stroke2DashCount,
+                                                     Stroke2DashArray,
+                                                     Stroke2DashOffset);
+              } else
+                {
+                  // invalid Pattern: defaulting to a black Pen
+                  if (Stroke2DashCount == 0)
+                    rl2_graph_set_solid_pen(ctx, 0, 0, 0, 255, Stroke2Width,
+                                            Stroke2LineCap, Stroke2LineJoin);
+                  else
+                    rl2_graph_set_dashed_pen(ctx, 0, 0, 0, 255, Stroke2Width,
+                                             Stroke2LineCap, Stroke2LineJoin,
+                                             Stroke2DashCount, Stroke2DashArray,
+                                             Stroke2DashOffset);
+                }
+            }
+        }
+      PreparePolygonPath(ctx, PerpendicularOffset2, DisplacementX2,
+                         DisplacementY2);
+      if (EnableFill2 == true && EnableStroke2)
+        {
+          // applying both Fill and Stroke
+          rl2_graph_fill_path(ctx, RL2_PRESERVE_PATH);
+          rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
+      } else if (EnableFill2 == true)
+        {
+          // applying Fill only
+          rl2_graph_fill_path(ctx, RL2_CLEAR_PATH);
+      } else if (EnableStroke2 == true)
+        {
+          // applying Stroke only
+          rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
+        }
+    }
+// creating the RGB and Alpha arrays
+  int half_transparency = 0;
+  unsigned char *rgb_array = rl2_graph_get_context_rgb_array(ctx);
+  unsigned char *alpha_array =
+    rl2_graph_get_context_alpha_array(ctx, &half_transparency);
+  rl2_graph_destroy_context(ctx);
+  if (pattern1 != NULL)
+    rl2_graph_destroy_pattern(pattern1);
+  if (pattern2 != NULL)
+    rl2_graph_destroy_pattern(pattern2);
+  if (pattern3 != NULL)
+    rl2_graph_destroy_pattern(pattern3);
+  if (pattern4 != NULL)
+    rl2_graph_destroy_pattern(pattern4);
+  if (rgb_array == NULL || alpha_array == NULL)
+    {
+      if (rgb_array != NULL)
+        free(rgb_array);
+      if (alpha_array != NULL)
+        free(alpha_array);
+      return;
+    }
+// creating the Preview from RGB and Alpha arrays
+  wxImage img(500, 300);
+  img.SetData(rgb_array);
+  img.SetAlpha(alpha_array);
+  wxBitmap bmp(img);
+  wxBitmap bmp2;
+  wxBrush brush;
+  wxMemoryDC dc;
+  wxBitmap white = wxBitmap(500, 300);
+  wxBitmap black = wxBitmap(500, 300);
+  switch (PreviewBackground)
+    {
+      case GUI_PREVIEW_BACKGROUND_WHITE:
+        dc.SelectObject(white);
+        brush = wxBrush(wxColour(255, 255, 255));
+        dc.SetBrush(brush);
+        dc.DrawRectangle(0, 0, 500, 300);
+        dc.SelectObject(wxNullBitmap);
+        bmp2 =
+          white.GetSubBitmap(wxRect(0, 0, white.GetWidth(), white.GetHeight()));
+        break;
+      case GUI_PREVIEW_BACKGROUND_BLACK:
+        dc.SelectObject(black);
+        brush = wxBrush(wxColour(0, 0, 0));
+        dc.SetBrush(brush);
+        dc.DrawRectangle(0, 0, 500, 300);
+        dc.SelectObject(wxNullBitmap);
+        bmp2 =
+          black.GetSubBitmap(wxRect(0, 0, black.GetWidth(), black.GetHeight()));
+        break;
+      default:
+        bmp2 =
+          PreviewBackBitmap.GetSubBitmap(wxRect
+                                         (0, 0, PreviewBackBitmap.GetWidth(),
+                                          PreviewBackBitmap.GetHeight()));
+        break;
+    };
+// printing the Preview over the currently selected background
+  dc.SelectObject(bmp2);
+  dc.DrawBitmap(bmp, 0, 0, true);
+  dc.SelectObject(wxNullBitmap);
+// updating the GUI Preview
+  SymbolizerPreview *previewCtrl =
+    (SymbolizerPreview *) FindWindow(ID_SYMBOLIZER_PREVIEW);
+  previewCtrl->SetBitmap(bmp2);
+}
+
+void SimplePolygonSymbolizerDialog::OnPageChanging(wxNotebookEvent & event)
+{
+//
+// TAB/PAGE selection changing
+//
+  bool ret;
+  switch (event.GetOldSelection())
+    {
+      case 0:
+        ret = RetrieveMainPage();
+        break;
+      case 1:
+        ret = RetrieveFill1Page();
+        break;
+      case 2:
+        ret = RetrieveStroke1Page();
+        break;
+      case 3:
+        ret = RetrieveFill2Page();
+        break;
+      case 4:
+        ret = RetrieveStroke2Page();
+        break;
+      case 5:
+        ret = RetrievePreviewPage();
+        break;
+    };
+  if (ret != true)
+    event.Veto();
+}
+
+void SimplePolygonSymbolizerDialog::OnPageChanged(wxNotebookEvent & event)
+{
+//
+// TAB/PAGE selection changed
+//
+  switch (event.GetSelection())
+    {
+      case 0:
+        UpdateMainPage();
+        break;
+      case 1:
+        UpdateFill1Page();
+        break;
+      case 2:
+        UpdateStroke1Page();
+        break;
+      case 3:
+        UpdateFill2Page();
+        break;
+      case 4:
+        UpdateStroke2Page();
+        break;
+      case 5:
+        UpdatePreviewPage();
+        break;
+    };
+}
+
+char *SimplePolygonSymbolizerDialog::DoCreateFeatureTypeXML()
+{
+//
+// creating the SLD/SE (XML) code - Feature Type
+//
+  char *str;
+  const char *cstr;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<FeatureTypeStyle version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Rule>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (MinScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MinScaleDenominator>%1.2f</MinScaleDenominator>\r\n", prev,
+         MinScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MaxScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MaxScaleDenominator>%1.2f</MaxScaleDenominator>\r\n", prev,
+         MaxScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  switch (Uom)
+    {
+      case GUI_UOM_METRE:
+        cstr = "http://www.opengeospatial.org/se/units/metre";
+        break;
+      case GUI_UOM_INCH:
+        cstr = "http://www.opengeospatial.org/se/units/inch";
+        break;
+      default:
+        cstr = "http://www.opengeospatial.org/se/units/pixel";
+        break;
+    };
+  xml = sqlite3_mprintf("%s\t\t<PolygonSymbolizer uom=\"%s\">\r\n", prev, cstr);
+  sqlite3_free(prev);
+  prev = xml;
+  if (EnableFill1 == true)
+    {
+      // Polygon Fill
+      xml = sqlite3_mprintf("%s\t\t\t<Fill>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (HasGraphicFill1 == true)
+        {
+          // using an External Graphic
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<GraphicFill>\r\n\t\t\t\t\t<Graphic>\r\n\t\t\t\t\t\t<ExternalGraphic>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Fill1XLinkHref.ToUTF8()) + 1];
+          strcpy(str, Fill1XLinkHref.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\" />\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Fill1MimeType.ToUTF8()) + 1];
+          strcpy(str, Fill1MimeType.ToUTF8());
+          xml =
+            sqlite3_mprintf("%s\t\t\t\t\t\t\t<Format>%s</Format>\r\n", prev,
+                            str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          if (EnableFill1Replacement == true)
+            {
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t<ColorReplacement>\r\n\t\t\t\t\t\t\t\t<Recode fallbackValue=\"#000000\">\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t\t<LookupValue>ExternalGraphic</LookupValue>\r\n\t\t\t\t\t\t\t\t\t<MapItem>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              str = new char[strlen(Fill1ColorReplacement.ToUTF8()) + 1];
+              strcpy(str, Fill1ColorReplacement.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t\t\t<Data>1</Data>\r\n\t\t\t\t\t\t\t\t\t\t<Value>%s</Value>\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t\t</MapItem>\r\n\t\t\t\t\t\t\t\t</Recode>\r\n\t\t\t\t\t\t\t</ColorReplacement>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+            }
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t</ExternalGraphic>\r\n\t\t\t\t\t</Graphic>\r\n\t\t\t\t</GraphicFill>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+      } else
+        {
+          // using a Solid Color
+          str = new char[strlen(Fill1Color.ToUTF8()) + 1];
+          strcpy(str, Fill1Color.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"fill\">%s</SvgParameter>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<SvgParameter name=\"fill-opacity\">%1.2f</SvgParameter>\r\n",
+         prev, Fill1Opacity);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t\t</Fill>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (EnableStroke1 == true)
+    {
+      // Polygon Stroke
+      xml = sqlite3_mprintf("%s\t\t\t<Stroke>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (HasGraphicStroke1 == true)
+        {
+          // using an External Graphic
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<GraphicStroke>\r\n\t\t\t\t\t<Graphic>\r\n\t\t\t\t\t\t<ExternalGraphic>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Stroke1XLinkHref.ToUTF8()) + 1];
+          strcpy(str, Stroke1XLinkHref.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\" />\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Stroke1MimeType.ToUTF8()) + 1];
+          strcpy(str, Stroke1MimeType.ToUTF8());
+          xml =
+            sqlite3_mprintf("%s\t\t\t\t\t\t\t<Format>%s</Format>\r\n", prev,
+                            str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          if (EnableStroke1Replacement == true)
+            {
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t<ColorReplacement>\r\n\t\t\t\t\t\t\t\t<Recode fallbackValue=\"#000000\">\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t\t<LookupValue>ExternalGraphic</LookupValue>\r\n\t\t\t\t\t\t\t\t\t<MapItem>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              str = new char[strlen(Stroke1ColorReplacement.ToUTF8()) + 1];
+              strcpy(str, Stroke1ColorReplacement.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t\t\t<Data>1</Data>\r\n\t\t\t\t\t\t\t\t\t\t<Value>%s</Value>\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t\t</MapItem>\r\n\t\t\t\t\t\t\t\t</Recode>\r\n\t\t\t\t\t\t\t</ColorReplacement>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+            }
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t</ExternalGraphic>\r\n\t\t\t\t\t</Graphic>\r\n\t\t\t\t</GraphicStroke>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+      } else
+        {
+          // using a Solid Color
+          str = new char[strlen(Stroke1Color.ToUTF8()) + 1];
+          strcpy(str, Stroke1Color.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"stroke\">%s</SvgParameter>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<SvgParameter name=\"stroke-opacity\">%1.2f</SvgParameter>\r\n",
+         prev, Stroke1Opacity);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<SvgParameter name=\"stroke-width\">%1.2f</SvgParameter>\r\n",
+         prev, Stroke1Width);
+      sqlite3_free(prev);
+      prev = xml;
+      switch (Stroke1LineJoin)
+        {
+          case RL2_PEN_JOIN_MITER:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">mitre</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          case RL2_PEN_JOIN_BEVEL:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">bevel</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          default:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">round</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+        };
+      switch (Stroke1LineCap)
+        {
+          case RL2_PEN_CAP_BUTT:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">butt</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          case RL2_PEN_CAP_SQUARE:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">square</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          default:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">round</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+        };
+      if (Stroke1DashCount > 0 && Stroke1DashArray != NULL)
+        {
+          wxString dash;
+          NormalizedDashArray(dash, 0, ' ');
+          str = new char[strlen(dash.ToUTF8()) + 1];
+          strcpy(str, dash.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"stroke-dasharray\">%s</SvgParameter>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          if (Stroke1DashOffset != 0.0)
+            {
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t<SvgParameter name=\"stroke-dashoffset\">%1.2f</SvgParameter>\r\n",
+                 prev, Stroke1DashOffset);
+              sqlite3_free(prev);
+              prev = xml;
+            }
+        }
+      xml = sqlite3_mprintf("%s\t\t\t</Stroke>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (DisplacementX1 != 0.0 || DisplacementY1 != 0.0)
+    {
+      xml = sqlite3_mprintf("%s\t\t\t<Displacement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t<DisplacementX>%1.4f</DisplacementX>\r\n",
+                        prev, DisplacementX1);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t<DisplacementY>%1.4f</DisplacementY>\r\n",
+                        prev, DisplacementY1);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t\t</Displacement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (PerpendicularOffset1 != 0.0)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t<PerpendicularOffset>%1.4f</PerpendicularOffset>\r\n", prev,
+         PerpendicularOffset1);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t</PolygonSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (EnablePolygon2 == true)
+    {
+      // Polygon #2
+      switch (Uom)
+        {
+          case GUI_UOM_METRE:
+            cstr = "http://www.opengeospatial.org/se/units/metre";
+            break;
+          case GUI_UOM_INCH:
+            cstr = "http://www.opengeospatial.org/se/units/inch";
+            break;
+          default:
+            cstr = "http://www.opengeospatial.org/se/units/pixel";
+            break;
+        };
+      xml =
+        sqlite3_mprintf("%s\t\t<PolygonSymbolizer uom=\"%s\">\r\n", prev, cstr);
+      sqlite3_free(prev);
+      prev = xml;
+      if (EnableFill2 == true)
+        {
+          // Polygon Fill
+          xml = sqlite3_mprintf("%s\t\t\t<Fill>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+          if (HasGraphicFill2 == true)
+            {
+              // using an External Graphic
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t<GraphicFill>\r\n\t\t\t\t\t<Graphic>\r\n\t\t\t\t\t\t<ExternalGraphic>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              str = new char[strlen(Fill2XLinkHref.ToUTF8()) + 1];
+              strcpy(str, Fill2XLinkHref.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\" />\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              str = new char[strlen(Fill2MimeType.ToUTF8()) + 1];
+              strcpy(str, Fill2MimeType.ToUTF8());
+              xml =
+                sqlite3_mprintf("%s\t\t\t\t\t\t\t<Format>%s</Format>\r\n", prev,
+                                str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              if (EnableFill2Replacement == true)
+                {
+                  xml =
+                    sqlite3_mprintf
+                    ("%s\t\t\t\t\t\t\t<ColorReplacement>\r\n\t\t\t\t\t\t\t\t<Recode fallbackValue=\"#000000\">\r\n",
+                     prev);
+                  sqlite3_free(prev);
+                  prev = xml;
+                  xml =
+                    sqlite3_mprintf
+                    ("%s\t\t\t\t\t\t\t\t\t<LookupValue>ExternalGraphic</LookupValue>\r\n\t\t\t\t\t\t\t\t\t<MapItem>\r\n",
+                     prev);
+                  sqlite3_free(prev);
+                  prev = xml;
+                  str = new char[strlen(Fill2ColorReplacement.ToUTF8()) + 1];
+                  strcpy(str, Fill2ColorReplacement.ToUTF8());
+                  xml =
+                    sqlite3_mprintf
+                    ("%s\t\t\t\t\t\t\t\t\t\t<Data>1</Data>\r\n\t\t\t\t\t\t\t\t\t\t<Value>%s</Value>\r\n",
+                     prev, str);
+                  delete[]str;
+                  sqlite3_free(prev);
+                  prev = xml;
+                  xml =
+                    sqlite3_mprintf
+                    ("%s\t\t\t\t\t\t\t\t\t</MapItem>\r\n\t\t\t\t\t\t\t\t</Recode>\r\n\t\t\t\t\t\t\t</ColorReplacement>\r\n",
+                     prev);
+                  sqlite3_free(prev);
+                  prev = xml;
+                }
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t</ExternalGraphic>\r\n\t\t\t\t\t</Graphic>\r\n\t\t\t\t</GraphicFill>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+          } else
+            {
+              // using a Solid Color
+              str = new char[strlen(Fill2Color.ToUTF8()) + 1];
+              strcpy(str, Fill2Color.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t<SvgParameter name=\"fill\">%s</SvgParameter>\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+            }
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"fill-opacity\">%1.2f</SvgParameter>\r\n",
+             prev, Fill2Opacity);
+          sqlite3_free(prev);
+          prev = xml;
+          xml = sqlite3_mprintf("%s\t\t\t</Fill>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (EnableStroke2 == true)
+        {
+          // Polygon Stroke
+          xml = sqlite3_mprintf("%s\t\t\t<Stroke>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+          if (HasGraphicStroke2 == true)
+            {
+              // using an External Graphic
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t<GraphicStroke>\r\n\t\t\t\t\t<Graphic>\r\n\t\t\t\t\t\t<ExternalGraphic>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              str = new char[strlen(Stroke2XLinkHref.ToUTF8()) + 1];
+              strcpy(str, Stroke2XLinkHref.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\" />\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              str = new char[strlen(Stroke2MimeType.ToUTF8()) + 1];
+              strcpy(str, Stroke2MimeType.ToUTF8());
+              xml =
+                sqlite3_mprintf("%s\t\t\t\t\t\t\t<Format>%s</Format>\r\n", prev,
+                                str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              if (EnableStroke2Replacement == true)
+                {
+                  xml =
+                    sqlite3_mprintf
+                    ("%s\t\t\t\t\t\t\t<ColorReplacement>\r\n\t\t\t\t\t\t\t\t<Recode fallbackValue=\"#000000\">\r\n",
+                     prev);
+                  sqlite3_free(prev);
+                  prev = xml;
+                  xml =
+                    sqlite3_mprintf
+                    ("%s\t\t\t\t\t\t\t\t\t<LookupValue>ExternalGraphic</LookupValue>\r\n\t\t\t\t\t\t\t\t\t<MapItem>\r\n",
+                     prev);
+                  sqlite3_free(prev);
+                  prev = xml;
+                  str = new char[strlen(Stroke2ColorReplacement.ToUTF8()) + 1];
+                  strcpy(str, Stroke2ColorReplacement.ToUTF8());
+                  xml =
+                    sqlite3_mprintf
+                    ("%s\t\t\t\t\t\t\t\t\t\t<Data>1</Data>\r\n\t\t\t\t\t\t\t\t\t\t<Value>%s</Value>\r\n",
+                     prev, str);
+                  delete[]str;
+                  sqlite3_free(prev);
+                  prev = xml;
+                  xml =
+                    sqlite3_mprintf
+                    ("%s\t\t\t\t\t\t\t\t\t</MapItem>\r\n\t\t\t\t\t\t\t\t</Recode>\r\n\t\t\t\t\t\t\t</ColorReplacement>\r\n",
+                     prev);
+                  sqlite3_free(prev);
+                  prev = xml;
+                }
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t</ExternalGraphic>\r\n\t\t\t\t\t</Graphic>\r\n\t\t\t\t</GraphicStroke>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+          } else
+            {
+              // using a Solid Color
+              str = new char[strlen(Stroke2Color.ToUTF8()) + 1];
+              strcpy(str, Stroke2Color.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t<SvgParameter name=\"stroke\">%s</SvgParameter>\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+            }
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"stroke-opacity\">%1.2f</SvgParameter>\r\n",
+             prev, Stroke2Opacity);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"stroke-width\">%1.2f</SvgParameter>\r\n",
+             prev, Stroke2Width);
+          sqlite3_free(prev);
+          prev = xml;
+          switch (Stroke2LineJoin)
+            {
+              case RL2_PEN_JOIN_MITER:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">mitre</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+              case RL2_PEN_JOIN_BEVEL:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">bevel</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+              default:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">round</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+            };
+          switch (Stroke2LineCap)
+            {
+              case RL2_PEN_CAP_BUTT:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">butt</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+              case RL2_PEN_CAP_SQUARE:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">square</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+              default:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">round</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+            };
+          if (Stroke2DashCount > 0 && Stroke2DashArray != NULL)
+            {
+              wxString dash;
+              NormalizedDashArray(dash, 1, ' ');
+              str = new char[strlen(dash.ToUTF8()) + 1];
+              strcpy(str, dash.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t<SvgParameter name=\"stroke-dasharray\">%s</SvgParameter>\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              if (Stroke2DashOffset != 0.0)
+                {
+                  xml =
+                    sqlite3_mprintf
+                    ("%s\t\t\t\t<SvgParameter name=\"stroke-dashoffset\">%1.2f</SvgParameter>\r\n",
+                     prev, Stroke2DashOffset);
+                  sqlite3_free(prev);
+                  prev = xml;
+                }
+            }
+          xml = sqlite3_mprintf("%s\t\t\t</Stroke>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (DisplacementX2 != 0.0 || DisplacementY2 != 0.0)
+        {
+          xml = sqlite3_mprintf("%s\t\t\t<Displacement>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<DisplacementX>%1.4f</DisplacementX>\r\n", prev,
+             DisplacementX2);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<DisplacementY>%1.4f</DisplacementY>\r\n", prev,
+             DisplacementY2);
+          sqlite3_free(prev);
+          prev = xml;
+          xml = sqlite3_mprintf("%s\t\t\t</Displacement>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (PerpendicularOffset2 != 0.0)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t<PerpendicularOffset>%1.4f</PerpendicularOffset>\r\n",
+             prev, PerpendicularOffset2);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t</PolygonSymbolizer>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t</Rule>\r\n</FeatureTypeStyle>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+char *SimplePolygonSymbolizerDialog::DoCreateSymbolizerXML()
+{
+//
+// creating the SLD/SE (XML) code - LineSymbolizer
+//
+  char *str;
+  const char *cstr;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<PolygonSymbolizer version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/Symbolizer.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  switch (Uom)
+    {
+      case GUI_UOM_METRE:
+        cstr = "http://www.opengeospatial.org/se/units/metre";
+        break;
+      case GUI_UOM_INCH:
+        cstr = "http://www.opengeospatial.org/se/units/inch";
+        break;
+      default:
+        cstr = "http://www.opengeospatial.org/se/units/pixel";
+        break;
+    };
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" uom=\"%s\">\r\n",
+     prev, cstr);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (EnableFill1 == true)
+    {
+      // Polygon Fill
+      xml = sqlite3_mprintf("%s\t<Fill>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (HasGraphicFill1 == true)
+        {
+          // using an External Graphic
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t<GraphicFill>\r\n\t\t\t<Graphic>\r\n\t\t\t\t<ExternalGraphic>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Fill1XLinkHref.ToUTF8()) + 1];
+          strcpy(str, Fill1XLinkHref.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\" />\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Fill1MimeType.ToUTF8()) + 1];
+          strcpy(str, Fill1MimeType.ToUTF8());
+          xml =
+            sqlite3_mprintf("%s\t\t\t\t\t<Format>%s</Format>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          if (EnableFill1Replacement == true)
+            {
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t<ColorReplacement>\r\n\t\t\t\t\t\t<Recode fallbackValue=\"#000000\">\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t<LookupValue>ExternalGraphic</LookupValue>\r\n\t\t\t\t\t\t\t<MapItem>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              str = new char[strlen(Fill1ColorReplacement.ToUTF8()) + 1];
+              strcpy(str, Fill1ColorReplacement.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t<Data>1</Data>\r\n\t\t\t\t\t\t\t\t<Value>%s</Value>\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t</MapItem>\r\n\t\t\t\t\t\t</Recode>\r\n\t\t\t\t\t</ColorReplacement>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+            }
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t</ExternalGraphic>\r\n\t\t\t</Graphic>\r\n\t\t</GraphicFill>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+      } else
+        {
+          // using a Solid Color
+          str = new char[strlen(Fill1Color.ToUTF8()) + 1];
+          strcpy(str, Fill1Color.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t<SvgParameter name=\"fill\">%s</SvgParameter>\r\n", prev,
+             str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<SvgParameter name=\"fill-opacity\">%1.2f</SvgParameter>\r\n",
+         prev, Fill1Opacity);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t</Fill>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (EnableStroke1 == true)
+    {
+      // Polygon Stroke
+      xml = sqlite3_mprintf("%s\t<Stroke>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (HasGraphicStroke1 == true)
+        {
+          // using an External Graphic
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t<GraphicStroke>\r\n\t\t\t<Graphic>\r\n\t\t\t\t<ExternalGraphic>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Stroke1XLinkHref.ToUTF8()) + 1];
+          strcpy(str, Stroke1XLinkHref.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\" />\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(Stroke1MimeType.ToUTF8()) + 1];
+          strcpy(str, Stroke1MimeType.ToUTF8());
+          xml =
+            sqlite3_mprintf("%s\t\t\t\t\t<Format>%s</Format>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          if (EnableStroke1Replacement == true)
+            {
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t<ColorReplacement>\r\n\t\t\t\t\t\t<Recode fallbackValue=\"#000000\">\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t<LookupValue>ExternalGraphic</LookupValue>\r\n\t\t\t\t\t\t\t<MapItem>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+              str = new char[strlen(Stroke1ColorReplacement.ToUTF8()) + 1];
+              strcpy(str, Stroke1ColorReplacement.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t\t<Data>1</Data>\r\n\t\t\t\t\t\t\t\t<Value>%s</Value>\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t\t</MapItem>\r\n\t\t\t\t\t\t</Recode>\r\n\t\t\t\t\t</ColorReplacement>\r\n",
+                 prev);
+              sqlite3_free(prev);
+              prev = xml;
+            }
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t</ExternalGraphic>\r\n\t\t\t</Graphic>\r\n\t\t</GraphicStroke>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+      } else
+        {
+          // using a Solid Color
+          str = new char[strlen(Stroke1Color.ToUTF8()) + 1];
+          strcpy(str, Stroke1Color.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t<SvgParameter name=\"stroke\">%s</SvgParameter>\r\n", prev,
+             str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<SvgParameter name=\"stroke-opacity\">%1.2f</SvgParameter>\r\n",
+         prev, Stroke1Opacity);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<SvgParameter name=\"stroke-width\">%1.2f</SvgParameter>\r\n",
+         prev, Stroke1Width);
+      sqlite3_free(prev);
+      prev = xml;
+      switch (Stroke1LineJoin)
+        {
+          case RL2_PEN_JOIN_MITER:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t<SvgParameter name=\"stroke-linejoin\">mitre</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          case RL2_PEN_JOIN_BEVEL:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t<SvgParameter name=\"stroke-linejoin\">bevel</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          default:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t<SvgParameter name=\"stroke-linejoin\">round</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+        };
+      switch (Stroke1LineCap)
+        {
+          case RL2_PEN_CAP_BUTT:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t<SvgParameter name=\"stroke-linecap\">butt</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          case RL2_PEN_CAP_SQUARE:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t<SvgParameter name=\"stroke-linecap\">square</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+          default:
+            xml =
+              sqlite3_mprintf
+              ("%s\t\t<SvgParameter name=\"stroke-linecap\">round</SvgParameter>\r\n",
+               prev);
+            sqlite3_free(prev);
+            prev = xml;
+            break;
+        };
+      if (Stroke1DashCount > 0 && Stroke1DashArray != NULL)
+        {
+          wxString dash;
+          NormalizedDashArray(dash, 0, ' ');
+          str = new char[strlen(dash.ToUTF8()) + 1];
+          strcpy(str, dash.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t<SvgParameter name=\"stroke-dasharray\">%s</SvgParameter>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          if (Stroke1DashOffset != 0.0)
+            {
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t<SvgParameter name=\"stroke-dashoffset\">%1.2f</SvgParameter>\r\n",
+                 prev, Stroke1DashOffset);
+              sqlite3_free(prev);
+              prev = xml;
+            }
+        }
+      xml = sqlite3_mprintf("%s\t</Stroke>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (DisplacementX1 != 0.0 || DisplacementY1 != 0.0)
+    {
+      xml = sqlite3_mprintf("%s\t<Displacement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t<DisplacementX>%1.4f</DisplacementX>\r\n", prev,
+                        DisplacementX1);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t<DisplacementY>%1.4f</DisplacementY>\r\n", prev,
+                        DisplacementY1);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t</Displacement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (PerpendicularOffset1 != 0.0)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t<PerpendicularOffset>%1.4f</PerpendicularOffset>\r\n", prev,
+         PerpendicularOffset1);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s</PolygonSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+void SimplePolygonSymbolizerDialog::OnInsert(wxCommandEvent & WXUNUSED(event))
+{
+//
+// inserting the VectorSymbolizer into the DBMS
+//
+  switch (GetBookCtrl()->GetSelection())
+    {
+      case 0:
+        RetrieveMainPage();
+        break;
+      case 1:
+        RetrieveFill1Page();
+        break;
+      case 2:
+        RetrieveStroke1Page();
+        break;
+      case 3:
+        RetrieveFill2Page();
+        break;
+      case 4:
+        RetrieveStroke2Page();
+        break;
+      case 5:
+        RetrievePreviewPage();
+        break;
+    };
+  if (FinalValidityCheck() == false)
+    {
+      GetBookCtrl()->ChangeSelection(0);
+      return;
+    }
+  char *xml;
+  if (MinScale == true || MaxScale == true || EnablePolygon2 == true)
+    xml = DoCreateFeatureTypeXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  if (MainFrame->DoInsertVectorSymbolizer(xml) == true)
+    wxMessageBox(wxT
+                 ("SLD/SE VectorSymbolizer successfully registered into the DBMS"),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  wxDialog::EndModal(wxID_OK);
+  wxDialog::EndModal(wxID_OK);
+}
+
+void SimplePolygonSymbolizerDialog::OnExport(wxCommandEvent & WXUNUSED(event))
+{
+//
+// exporting the VectorSymbolizer as an external file
+//
+  int ret;
+  wxString path;
+  wxString lastDir;
+  switch (GetBookCtrl()->GetSelection())
+    {
+      case 0:
+        RetrieveMainPage();
+        break;
+      case 1:
+        RetrieveFill1Page();
+        break;
+      case 2:
+        RetrieveStroke1Page();
+        break;
+      case 3:
+        RetrieveFill2Page();
+        break;
+      case 4:
+        RetrieveStroke2Page();
+        break;
+      case 5:
+        RetrievePreviewPage();
+        break;
+    };
+  if (FinalValidityCheck() == false)
+    {
+      GetBookCtrl()->ChangeSelection(0);
+      return;
+    }
+  wxFileDialog fileDialog(this,
+                          wxT
+                          ("Exporting an SLD/SE PolygonSymbolizer to a file"),
+                          wxT(""), Name + wxT(".xml"),
+                          wxT("XML Document|*.xml|All files (*.*)|*.*"),
+                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      wxFileName file(fileDialog.GetPath());
+      path = file.GetPath();
+      path += file.GetPathSeparator();
+      path += file.GetName();
+      lastDir = file.GetPath();
+      path = fileDialog.GetPath();
+      FILE *out = fopen(path.ToUTF8(), "wb");
+      if (out == NULL)
+        wxMessageBox(wxT("ERROR: unable to create:\n\n\"") + path + wxT("\""),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else
+        {
+          char *xml;
+          if (MinScale == true || MaxScale == true || EnablePolygon2 == true)
+            xml = DoCreateFeatureTypeXML();
+          else
+            xml = DoCreateSymbolizerXML();
+          fwrite(xml, 1, strlen(xml), out);
+          sqlite3_free(xml);
+          fclose(out);
+          wxMessageBox(wxT
+                       ("SLD/SE PolygonSymbolizer successfully saved into:\n\n\"")
+                       + path + wxT("\""), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+void SimplePolygonSymbolizerDialog::OnCopy(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Copying the VectorSymbolizer into the Clipboard 
+//
+  switch (GetBookCtrl()->GetSelection())
+    {
+      case 0:
+        RetrieveMainPage();
+        break;
+      case 1:
+        RetrieveFill1Page();
+        break;
+      case 2:
+        RetrieveStroke1Page();
+        break;
+      case 3:
+        RetrieveFill2Page();
+        break;
+      case 4:
+        RetrieveStroke2Page();
+        break;
+      case 5:
+        RetrievePreviewPage();
+        break;
+    };
+  if (FinalValidityCheck() == false)
+    {
+      GetBookCtrl()->ChangeSelection(0);
+      return;
+    }
+  char *xml;
+  if (MinScale == true || MaxScale == true || EnablePolygon2 == true)
+    xml = DoCreateFeatureTypeXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  wxString XMLstring = wxString::FromUTF8(xml);
+  if (wxTheClipboard->Open())
+    {
+      wxTheClipboard->SetData(new wxTextDataObject(XMLstring));
+      wxTheClipboard->Close();
+    }
+}
+
+void SimplePolygonSymbolizerDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
diff --git a/VectorSymbolizers2.cpp b/VectorSymbolizers2.cpp
new file mode 100644
index 0000000..b76c60b
--- /dev/null
+++ b/VectorSymbolizers2.cpp
@@ -0,0 +1,6184 @@
+/*
+/ VectorSymbolizers2.cpp
+/ various dialog classes
+/
+/ version 1.8, 2015 April 21
+/
+/ Author: Sandro Furieri a-furieri at lqt.it
+/
+/ Copyright (C) 2015  Alessandro Furieri
+/
+/    This program is free software: you can redistribute it and/or modify
+/    it under the terms of the GNU General Public License as published by
+/    the Free Software Foundation, either version 3 of the License, or
+/    (at your option) any later version.
+/
+/    This program is distributed in the hope that it will be useful,
+/    but WITHOUT ANY WARRANTY; without even the implied warranty of
+/    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/    GNU General Public License for more details.
+/
+/    You should have received a copy of the GNU General Public License
+/    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+/
+*/
+
+#include "Classdef.h"
+
+#include "wx/spinctrl.h"
+#include "wx/filename.h"
+#include "wx/colordlg.h"
+#include "wx/tokenzr.h"
+#include "wx/clipbrd.h"
+
+#include <rasterlite2/rasterlite2.h>
+#include <rasterlite2/rl2graphics.h>
+#include <rasterlite2/rl2svg.h>
+
+SimplePointSymbolizerDialog::SimplePointSymbolizerDialog()
+{
+// ctor
+  StrokeDashArray = NULL;
+  List = NULL;
+}
+
+SimplePointSymbolizerDialog::~SimplePointSymbolizerDialog()
+{
+// dtor
+  if (StrokeDashArray != NULL)
+    delete[]StrokeDashArray;
+  if (List)
+    delete List;
+}
+
+bool SimplePointSymbolizerDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Uom = GUI_UOM_PIXEL;
+  MinScale = false;
+  MaxScale = false;
+  Opacity = 1.0;
+  Size = 16.0;
+  Rotation = 0.0;
+  AnchorPointX = 0.5;
+  AnchorPointY = 0.5;
+  DisplacementX = 0.0;
+  DisplacementY = 0.0;
+  OnlyRescaleSVG = true;
+  HasGraphic = false;
+  EnableFill = true;
+  EnableStroke = true;
+  StrokeColor = wxT("#000000");
+  FillColor = wxT("#808080");
+  EnableColorReplacement = false;
+  ColorReplacement = wxT("#000000");
+  WellKnownMark = RL2_GRAPHIC_MARK_SQUARE;
+  StrokeWidth = 1.0;
+  StrokeLineJoin = RL2_PEN_JOIN_ROUND;
+  StrokeLineCap = RL2_PEN_CAP_ROUND;
+  StrokeDashCount = 0;
+  StrokeDashOffset = 0.0;
+  PreviewBackground = GUI_PREVIEW_BACKGROUND_CHECKED;
+  Crosshair = true;
+  List = MainFrame->FindExternalGraphic(false);
+
+  if (wxPropertySheetDialog::Create
+      (parent, wxID_ANY, wxT("Simple Point Symbolizer")) == false)
+    return false;
+  wxBookCtrlBase *book = GetBookCtrl();
+// creates individual panels
+  wxPanel *mainPage = CreateMainPage(book);
+  book->AddPage(mainPage, wxT("General"), true);
+  wxPanel *positionPage = CreatePositionPage(book);
+  book->AddPage(positionPage, wxT("Position"), false);
+  wxPanel *graphicPage = CreateGraphicPage(book);
+  book->AddPage(graphicPage, wxT("Graphic"), false);
+  wxPanel *markPage = CreateMarkPage(book);
+  book->AddPage(markPage, wxT("Mark"), false);
+  wxPanel *previewPage = CreatePreviewPage(book);
+  book->AddPage(previewPage, wxT("Preview"), false);
+
+  CreateButtons();
+  LayoutDialog();
+// appends event handler for TAB/PAGE changing
+  Connect(wxID_ANY, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnPageChanging);
+  Connect(wxID_ANY, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
+          (wxObjectEventFunction) & SimplePointSymbolizerDialog::OnPageChanged);
+// appends event handler for buttons
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimplePointSymbolizerDialog::OnQuit);
+  Connect(ID_SYMBOLIZER_INSERT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimplePointSymbolizerDialog::OnInsert);
+  Connect(ID_SYMBOLIZER_EXPORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimplePointSymbolizerDialog::OnExport);
+  Connect(ID_SYMBOLIZER_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimplePointSymbolizerDialog::OnCopy);
+// centers the dialog window
+  Centre();
+  UpdateMainPage();
+  return true;
+}
+
+wxPanel *SimplePointSymbolizerDialog::CreateMainPage(wxWindow * parent)
+{
+//
+// creating the MAIN page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_MAIN);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+// first row: the PointSymbolizer Name
+  wxBoxSizer *nameSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(nameSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *nameLabel = new wxStaticText(panel, wxID_STATIC, wxT("&Name:"));
+  nameSizer->Add(nameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *nameCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_NAME, wxT(""),
+                                        wxDefaultPosition, wxSize(600, 22));
+  nameSizer->Add(nameCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the PointSymbolizer Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the PointSymbolizer Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_ABSTRACT, wxT(""),
+                   wxDefaultPosition, wxSize(600, 60),
+                   wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: UOM and Visibility Range
+  boxSizer->AddSpacer(50);
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// fourth row A: Unit Of Measure - UOM
+  wxString uom[3];
+  uom[0] = wxT("&Pixel");
+  uom[1] = wxT("&Metre");
+  uom[2] = wxT("&Inch");
+  wxRadioBox *uomBox = new wxRadioBox(panel, ID_SYMBOLIZER_UOM,
+                                      wxT("&Unit Of Measure"),
+                                      wxDefaultPosition,
+                                      wxDefaultSize, 3,
+                                      uom, 1,
+                                      wxRA_SPECIFY_ROWS);
+  miscSizer->Add(uomBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  uomBox->SetSelection(0);
+// fourth row B: optional Visibility Range
+  miscSizer->AddSpacer(50);
+  wxBoxSizer *visibilityBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(visibilityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *visibilityBox = new wxStaticBox(panel, wxID_STATIC,
+                                               wxT("Visibility Range"),
+                                               wxDefaultPosition,
+                                               wxDefaultSize);
+  wxBoxSizer *visibilitySizer =
+    new wxStaticBoxSizer(visibilityBox, wxHORIZONTAL);
+  visibilityBoxSizer->Add(visibilitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL,
+                          5);
+  wxString range[4];
+  range[0] = wxT("&None");
+  range[1] = wxT("&Min");
+  range[2] = wxT("&Max");
+  range[3] = wxT("&Both");
+  wxRadioBox *rangeBox = new wxRadioBox(panel, ID_SYMBOLIZER_MINMAX_SCALE,
+                                        wxT("&Range Type"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 4,
+                                        range, 2,
+                                        wxRA_SPECIFY_COLS);
+  visibilitySizer->Add(rangeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  rangeBox->SetSelection(0);
+  visibilitySizer->AddSpacer(20);
+  wxBoxSizer *scaleBoxSizer = new wxBoxSizer(wxVERTICAL);
+  visibilitySizer->Add(scaleBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *scaleMinSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMinSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *minScaleLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Min Scale:"));
+  scaleMinSizer->Add(minScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *minScaleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_MIN_SCALE, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  minScaleCtrl->Enable(false);
+  scaleMinSizer->Add(minScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *scaleMaxSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMaxSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *maxScaleLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Max Scale:"));
+  scaleMaxSizer->Add(maxScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *maxScaleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_MAX_SCALE, wxT("+Infinite"),
+                   wxDefaultPosition, wxSize(100, 22));
+  maxScaleCtrl->Enable(false);
+  scaleMaxSizer->Add(maxScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// fifth row: Symbol Type
+  boxSizer->AddSpacer(25);
+  wxBoxSizer *typeSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(typeSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxString type[2];
+  type[0] = wxT("&Graphic");
+  type[1] = wxT("&Mark");
+  wxRadioBox *typeBox = new wxRadioBox(panel, ID_SYMBOLIZER_TYPE,
+                                       wxT("&Symbol Type"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 2,
+                                       type, 1,
+                                       wxRA_SPECIFY_ROWS);
+  typeSizer->Add(typeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  typeBox->SetSelection(1);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_UOM, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdUomChanged);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdScaleChanged);
+  Connect(ID_SYMBOLIZER_TYPE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdTypeChanged);
+  return panel;
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdUomChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// UOM selection changed
+//
+  wxRadioBox *uomCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_UOM);
+  switch (uomCtrl->GetSelection())
+    {
+      case 1:
+        Uom = GUI_UOM_METRE;
+        break;
+      case 2:
+        Uom = GUI_UOM_INCH;
+        break;
+      default:
+        Uom = GUI_UOM_PIXEL;
+        break;
+    };
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdScaleChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Visibility Range selection changed
+//
+  wxRadioBox *scaleModeCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  switch (scaleModeCtrl->GetSelection())
+    {
+      case 0:
+        MinScale = false;
+        MaxScale = false;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 1:
+        MinScale = true;
+        MaxScale = false;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 2:
+        MinScale = false;
+        MaxScale = true;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+      case 3:
+        MinScale = true;
+        MaxScale = true;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+    };
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdTypeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Symbol Type selection changed
+//
+  wxRadioBox *typeCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_TYPE);
+  switch (typeCtrl->GetSelection())
+    {
+      case 1:
+        HasGraphic = false;
+        break;
+      default:
+        HasGraphic = true;
+        break;
+    };
+}
+
+wxPanel *SimplePointSymbolizerDialog::CreatePositionPage(wxWindow * parent)
+{
+//
+// creating the Position page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_POSITION);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+// first row A: Opacity 
+  wxBoxSizer *opacityBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(opacityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *opacityBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("Opacity"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *opacitySizer = new wxStaticBoxSizer(opacityBox, wxVERTICAL);
+  opacityBoxSizer->Add(opacitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxSlider *opacityCtrl =
+    new wxSlider(panel, ID_SYMBOLIZER_OPACITY, 100, 0, 100,
+                 wxDefaultPosition, wxSize(600, 45),
+                 wxSL_HORIZONTAL | wxSL_LABELS);
+  opacitySizer->Add(opacityCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// second row: Size and Rotation
+  wxBoxSizer *sizeBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(sizeBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// second row A: Size
+  wxStaticBox *sizeBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("Size"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *sizeSizer = new wxStaticBoxSizer(sizeBox, wxVERTICAL);
+  sizeBoxSizer->Add(sizeSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 20);
+  wxBoxSizer *size1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  sizeSizer->Add(size1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxTextCtrl *sizeCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_SIZE, wxT("16.0"),
+                                        wxDefaultPosition, wxSize(100, 22));
+  size1Sizer->Add(sizeCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// second row B: Rotation
+  wxStaticBox *rotBox = new wxStaticBox(panel, wxID_STATIC,
+                                        wxT("Rotation"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize);
+  wxBoxSizer *rotSizer = new wxStaticBoxSizer(rotBox, wxVERTICAL);
+  sizeBoxSizer->Add(rotSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 20);
+  wxBoxSizer *rot1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  rotSizer->Add(rot1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxTextCtrl *rotCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_ROTATION, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  rot1Sizer->Add(rotCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// third row: AnchorPoint and Displacement
+  wxBoxSizer *anchorBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(anchorBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// third row A: Anchor Point
+  wxStaticBox *anchorBox = new wxStaticBox(panel, wxID_STATIC,
+                                           wxT("Anchor Point"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize);
+  wxBoxSizer *anchorSizer = new wxStaticBoxSizer(anchorBox, wxVERTICAL);
+  anchorBoxSizer->Add(anchorSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 20);
+  wxBoxSizer *anchor1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  anchorSizer->Add(anchor1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *anchor1Label = new wxStaticText(panel, wxID_STATIC, wxT("X"));
+  anchor1Sizer->Add(anchor1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *anchorXCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_ANCHOR_X, wxT("0.5"),
+                   wxDefaultPosition, wxSize(100, 22));
+  anchor1Sizer->Add(anchorXCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *anchor2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  anchorSizer->Add(anchor2Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *anchor2Label = new wxStaticText(panel, wxID_STATIC, wxT("Y"));
+  anchor2Sizer->Add(anchor2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *anchorYCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_ANCHOR_Y, wxT("0.5"),
+                   wxDefaultPosition, wxSize(100, 22));
+  anchor2Sizer->Add(anchorYCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// third row B: Displacement
+  wxStaticBox *displacementBox = new wxStaticBox(panel, wxID_STATIC,
+                                                 wxT("Displacement"),
+                                                 wxDefaultPosition,
+                                                 wxDefaultSize);
+  wxBoxSizer *displacementSizer =
+    new wxStaticBoxSizer(displacementBox, wxVERTICAL);
+  anchorBoxSizer->Add(displacementSizer, 0,
+                      wxALIGN_CENTER_HORIZONTAL | wxALL, 20);
+  wxBoxSizer *displ1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  displacementSizer->Add(displ1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *displ1Label = new wxStaticText(panel, wxID_STATIC, wxT("X"));
+  displ1Sizer->Add(displ1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *displacementXCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_DISPLACEMENT_X, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  displ1Sizer->Add(displacementXCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *displ2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  displacementSizer->Add(displ2Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *displ2Label = new wxStaticText(panel, wxID_STATIC, wxT("Y"));
+  displ2Sizer->Add(displ2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *displacementYCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_DISPLACEMENT_Y, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  displ2Sizer->Add(displacementYCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+  return panel;
+}
+
+wxPanel *SimplePointSymbolizerDialog::CreateGraphicPage(wxWindow * parent)
+{
+//
+// creating the Graphic page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_GRAPHIC);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+
+// GRID to select an External Graphic
+  wxBoxSizer *graphicSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(graphicSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  graphicSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *gridBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("External Graphic resources"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxHORIZONTAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(panel, ID_SYMBOLIZER_GRAPHIC, wxDefaultPosition,
+               wxSize(500, 250), wxALWAYS_SHOW_SB);
+  int count = 0;
+  ExternalGraphic *pE = List->GetFirst();
+  while (pE)
+    {
+      // counting how many lines are there
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 4, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("Graphic"));
+  GridCtrl->SetColLabelValue(1, wxT("Title"));
+  GridCtrl->SetColLabelValue(2, wxT("Abstract"));
+  GridCtrl->SetColLabelValue(3, wxT("MimeType"));
+  count = 0;
+  pE = List->GetFirst();
+  while (pE)
+    {
+      // feeding grid rows
+      MyGraphicCellRenderer *renderer = new MyGraphicCellRenderer;
+      renderer->SetGraphic(pE->GetGraphic());
+      GridCtrl->SetCellRenderer(count, 0, renderer);
+      GridCtrl->SetCellValue(count, 1, pE->GetTitle());
+      GridCtrl->SetCellValue(count, 2, pE->GetAbstract());
+      GridCtrl->SetCellValue(count, 3, pE->GetMimeType());
+      count++;
+      pE = pE->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  GridCtrl->Enable(false);
+// second row C: Color Replacement
+  wxBoxSizer *replacementBoxSizer = new wxBoxSizer(wxVERTICAL);
+  GridSizer->Add(replacementBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *replacementBox = new wxStaticBox(panel, wxID_STATIC,
+                                                wxT("Color Replacement"),
+                                                wxDefaultPosition,
+                                                wxDefaultSize);
+  wxBoxSizer *replacementSizer =
+    new wxStaticBoxSizer(replacementBox, wxVERTICAL);
+  replacementBoxSizer->Add(replacementSizer, 0,
+                           wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxCheckBox *enableReplacementCtrl =
+    new wxCheckBox(panel, ID_SYMBOLIZER_ENABLE_COLOR_REPLACEMENT,
+                   wxT("Enable"),
+                   wxDefaultPosition, wxDefaultSize);
+  enableReplacementCtrl->SetValue(false);
+  enableReplacementCtrl->Enable(false);
+  replacementSizer->Add(enableReplacementCtrl, 0,
+                        wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *replacement1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  replacementSizer->Add(replacement1Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *replacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_COLOR_REPLACEMENT,
+                   ColorReplacement,
+                   wxDefaultPosition, wxSize(80, 22));
+  replacement1Sizer->Add(replacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  replacementCtrl->Enable(false);
+  wxTextCtrl *sampleReplacementCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_COLOR_REPLACEMENT_HEX,
+                   wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  wxColour back = wxColour(0, 0, 0);
+  sampleReplacementCtrl->SetBackgroundColour(back);
+  replacement1Sizer->Add(sampleReplacementCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  wxButton *pick = new wxButton(panel, ID_SYMBOLIZER_REPLACEMENT_PICKER_BTN,
+                                wxT("&Pick a color"));
+  replacementSizer->Add(pick, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  pick->Enable(false);
+// third row: rescaling only SVG symbols
+  wxCheckBox *rescaleCtrl = new wxCheckBox(panel, ID_ONLY_RESCALE_SVG_SYMBOLS,
+                                           wxT
+                                           ("Rescaling applies only to SVG symbols"),
+                                           wxDefaultPosition, wxDefaultSize);
+  rescaleCtrl->SetValue(true);
+  boxSizer->Add(rescaleCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  rescaleCtrl->Enable(false);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_REPLACEMENT_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdColorReplacementPicker);
+  Connect(ID_SYMBOLIZER_ENABLE_COLOR_REPLACEMENT,
+          wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdEnableReplacementChanged);
+  Connect(ID_SYMBOLIZER_COLOR_REPLACEMENT, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdColorReplacementChanged);
+  Connect(ID_ONLY_RESCALE_SVG_SYMBOLS, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdOnlyRescaleSVG);
+  return panel;
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdColorReplacementPicker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR_REPLACEMENT);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdEnableReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Graphic ColorReplacement enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_ENABLE_COLOR_REPLACEMENT);
+  if (enableCtrl->IsChecked() == true)
+    EnableColorReplacement = true;
+  else
+    EnableColorReplacement = false;
+  RetrieveGraphicPage(false);
+  UpdateGraphicPage();
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdColorReplacementChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Graphic Color Replacement changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR_REPLACEMENT);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR_REPLACEMENT_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdOnlyRescaleSVG(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Rescaling only SVG symbols enable/disable
+//
+  wxCheckBox *rescaleCtrl =
+    (wxCheckBox *) FindWindow(ID_ONLY_RESCALE_SVG_SYMBOLS);
+  if (rescaleCtrl->IsChecked() == true)
+    OnlyRescaleSVG = true;
+  else
+    OnlyRescaleSVG = false;
+}
+
+wxPanel *SimplePointSymbolizerDialog::CreateMarkPage(wxWindow * parent)
+{
+//
+// creating the Mark page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_MARK);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *box1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  topSizer->Add(box1Sizer, 0, wxALIGN_CENTER | wxALL, 5);
+// Well Known Mark Name
+  wxBoxSizer *markSizer = new wxBoxSizer(wxHORIZONTAL);
+  box1Sizer->Add(markSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxString mark[6];
+  mark[0] = wxT("&Square");
+  mark[1] = wxT("&Circle");
+  mark[2] = wxT("&Triangle");
+  mark[3] = wxT("&Star");
+  mark[4] = wxT("&Cross");
+  mark[5] = wxT("&X");
+  wxRadioBox *markBox = new wxRadioBox(panel, ID_SYMBOLIZER_MARK,
+                                       wxT("&Mark"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 6,
+                                       mark, 1,
+                                       wxRA_SPECIFY_COLS);
+  markSizer->Add(markBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  markBox->SetSelection(0);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  box1Sizer->Add(boxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// first row: Fill
+  wxBoxSizer *fillBoxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(fillBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxStaticBox *fillBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("Fill"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *fillSizer = new wxStaticBoxSizer(fillBox, wxHORIZONTAL);
+  fillBoxSizer->Add(fillSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// first row A: Fill Enable
+  wxCheckBox *enableFillCtrl = new wxCheckBox(panel, ID_SYMBOLIZER_FILL_ENABLE,
+                                              wxT("Enable"),
+                                              wxDefaultPosition, wxDefaultSize);
+  enableFillCtrl->SetValue(true);
+  fillSizer->Add(enableFillCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// first row B: Fill Color
+  wxStaticBox *colorFillBox = new wxStaticBox(panel, wxID_STATIC,
+                                              wxT("Fill Color"),
+                                              wxDefaultPosition,
+                                              wxDefaultSize);
+  wxBoxSizer *colorFillSizer = new wxStaticBoxSizer(colorFillBox, wxVERTICAL);
+  fillSizer->Add(colorFillSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *fill1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  colorFillSizer->Add(fill1Sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxTextCtrl *fillColorCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_FILL_COLOR, FillColor,
+                   wxDefaultPosition, wxSize(80, 22));
+  fill1Sizer->Add(fillColorCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *sampleFillCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_FILL_PICKER_HEX, wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  wxColour back = wxColour(128, 128, 128);
+  sampleFillCtrl->SetBackgroundColour(back);
+  fill1Sizer->Add(sampleFillCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *pickFill =
+    new wxButton(panel, ID_SYMBOLIZER_FILL_PICKER_BTN, wxT("&Pick a color"));
+  fill1Sizer->Add(pickFill, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// second row: Stroke
+  wxBoxSizer *strokeBoxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(strokeBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxStaticBox *strokeBox = new wxStaticBox(panel, wxID_STATIC,
+                                           wxT("Stroke"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize);
+  wxBoxSizer *strokeXSizer = new wxStaticBoxSizer(strokeBox, wxVERTICAL);
+  strokeBoxSizer->Add(strokeXSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *strokeSizer = new wxBoxSizer(wxHORIZONTAL);
+  strokeXSizer->Add(strokeSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// second row A: Stroke Enable
+  wxCheckBox *enableStrokeCtrl =
+    new wxCheckBox(panel, ID_SYMBOLIZER_STROKE_ENABLE,
+                   wxT("Enable"),
+                   wxDefaultPosition, wxDefaultSize);
+  enableStrokeCtrl->SetValue(true);
+  strokeSizer->Add(enableStrokeCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// second row B: Stroke Color
+  wxStaticBox *colorStrokeBox = new wxStaticBox(panel, wxID_STATIC,
+                                                wxT("Stroke Color"),
+                                                wxDefaultPosition,
+                                                wxDefaultSize);
+  wxBoxSizer *colorStrokeSizer =
+    new wxStaticBoxSizer(colorStrokeBox, wxVERTICAL);
+  strokeSizer->Add(colorStrokeSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *stroke1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  colorStrokeSizer->Add(stroke1Sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxTextCtrl *strokeColorCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE_COLOR, StrokeColor,
+                   wxDefaultPosition, wxSize(80, 22));
+  stroke1Sizer->Add(strokeColorCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *sampleStrokeCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE_PICKER_HEX, wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  back = wxColour(0, 0, 0);
+  sampleStrokeCtrl->SetBackgroundColour(back);
+  stroke1Sizer->Add(sampleStrokeCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *pickStroke =
+    new wxButton(panel, ID_SYMBOLIZER_STROKE_PICKER_BTN, wxT("&Pick a color"));
+  stroke1Sizer->Add(pickStroke, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// second row C: StrokeWidth
+  wxStaticBox *widthBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Stroke Width"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *widthSizer = new wxStaticBoxSizer(widthBox, wxVERTICAL);
+  strokeSizer->Add(widthSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *widthCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE_WIDTH, wxT("1.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  widthSizer->Add(widthCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// third row: Stroke-LineJoin, Stroke-LineCap and Stroke-Dasharray 
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  strokeXSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// third row B: LineJoin
+  wxString join[3];
+  join[0] = wxT("&Mitre");
+  join[1] = wxT("&Round");
+  join[2] = wxT("&Bevel");
+  wxRadioBox *joinBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE_LINEJOIN,
+                                       wxT("&Line Join"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 3,
+                                       join, 1,
+                                       wxRA_SPECIFY_COLS);
+  miscSizer->Add(joinBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  joinBox->SetSelection(1);
+// third row C: LineCap
+  wxString cap[3];
+  cap[0] = wxT("&Butt");
+  cap[1] = wxT("&Round");
+  cap[2] = wxT("&Square");
+  wxRadioBox *capBox = new wxRadioBox(panel, ID_SYMBOLIZER_STROKE_LINECAP,
+                                      wxT("&Line Cap"),
+                                      wxDefaultPosition,
+                                      wxDefaultSize, 3,
+                                      cap, 1,
+                                      wxRA_SPECIFY_COLS);
+  miscSizer->Add(capBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  capBox->SetSelection(1);
+// third row D: DashArray and DashOffset
+  wxBoxSizer *dashBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(dashBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *dashBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("Dashed/Dotted Stroke"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *dashSizer = new wxStaticBoxSizer(dashBox, wxVERTICAL);
+  dashBoxSizer->Add(dashSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *dash1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  dashSizer->Add(dash1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *dash1Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT("Dash Array:"));
+  dash1Sizer->Add(dash1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *dashArrayCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE_DASHARRAY, wxT(""),
+                   wxDefaultPosition, wxSize(200, 22));
+  dash1Sizer->Add(dashArrayCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxStaticText *dash2Label =
+    new wxStaticText(panel, wxID_STATIC, wxT("e.g. 10,3,2,3"));
+  dash2Label->SetForegroundColour(wxColour(255, 0, 0));
+  dash1Sizer->Add(dash2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *dash2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  dashSizer->Add(dash2Sizer, 0, wxALIGN_LEFT | wxALL, 0);
+  wxStaticText *dashOffsetLabel = new wxStaticText(panel, wxID_STATIC,
+                                                   wxT("Dash Offset:"));
+  dash2Sizer->Add(dashOffsetLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *dashOffsetCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_STROKE_DASHOFFSET, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  dash2Sizer->Add(dashOffsetCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_MARK, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdMarkChanged);
+  Connect(ID_SYMBOLIZER_FILL_ENABLE, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdFillChanged);
+  Connect(ID_SYMBOLIZER_FILL_COLOR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdColorFillChanged);
+  Connect(ID_SYMBOLIZER_FILL_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdColorFillPicker);
+  Connect(ID_SYMBOLIZER_STROKE_ENABLE, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdStrokeChanged);
+  Connect(ID_SYMBOLIZER_STROKE_COLOR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdColorStrokeChanged);
+  Connect(ID_SYMBOLIZER_STROKE_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdColorStrokePicker);
+  Connect(ID_SYMBOLIZER_STROKE_LINEJOIN, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdLineJoinChanged);
+  Connect(ID_SYMBOLIZER_STROKE_LINECAP, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdLineCapChanged);
+  return panel;
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdMarkChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Mark selection changed
+//
+  wxRadioBox *markCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MARK);
+  switch (markCtrl->GetSelection())
+    {
+      case 1:
+        WellKnownMark = RL2_GRAPHIC_MARK_CIRCLE;
+        break;
+      case 2:
+        WellKnownMark = RL2_GRAPHIC_MARK_TRIANGLE;
+        break;
+      case 3:
+        WellKnownMark = RL2_GRAPHIC_MARK_STAR;
+        break;
+      case 4:
+        WellKnownMark = RL2_GRAPHIC_MARK_CROSS;
+        break;
+      case 5:
+        WellKnownMark = RL2_GRAPHIC_MARK_X;
+        break;
+      default:
+        WellKnownMark = RL2_GRAPHIC_MARK_SQUARE;
+        break;
+    };
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdFillChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Fill enable/disable 
+//
+  wxCheckBox *enableCtrl = (wxCheckBox *) FindWindow(ID_SYMBOLIZER_FILL_ENABLE);
+  if (enableCtrl->IsChecked() == true)
+    EnableFill = true;
+  else
+    EnableFill = false;
+  RetrieveMarkPage(false);
+  UpdateMarkPage();
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdColorFillChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Fill color changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_PICKER_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdColorFillPicker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_COLOR);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdStrokeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke enable/disable 
+//
+  wxCheckBox *enableCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE_ENABLE);
+  if (enableCtrl->IsChecked() == true)
+    EnableStroke = true;
+  else
+    EnableStroke = false;
+  RetrieveMarkPage(false);
+  UpdateMarkPage();
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdColorStrokeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Stroke color changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE_PICKER_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdColorStrokePicker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE_COLOR);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdLineJoinChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// LineJoin selection changed
+//
+  wxRadioBox *lineJoinCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE_LINEJOIN);
+  switch (lineJoinCtrl->GetSelection())
+    {
+      case 0:
+        StrokeLineJoin = RL2_PEN_JOIN_MITER;
+        break;
+      case 2:
+        StrokeLineJoin = RL2_PEN_JOIN_BEVEL;
+        break;
+      default:
+        StrokeLineJoin = RL2_PEN_JOIN_ROUND;
+        break;
+    };
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdLineCapChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// LineCap selection changed
+//
+  wxRadioBox *lineCapCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE_LINECAP);
+  switch (lineCapCtrl->GetSelection())
+    {
+      case 0:
+        StrokeLineCap = RL2_PEN_CAP_BUTT;
+        break;
+      case 2:
+        StrokeLineCap = RL2_PEN_CAP_SQUARE;
+        break;
+      default:
+        StrokeLineCap = RL2_PEN_CAP_ROUND;
+        break;
+    };
+}
+
+wxPanel *SimplePointSymbolizerDialog::CreatePreviewPage(wxWindow * parent)
+{
+//
+// creating the Preview page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_PREVIEW);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxHORIZONTAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+  wxBoxSizer *previewBoxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(previewBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// creating a control to show the PoinrSymbolizer Preview
+  wxStaticBox *previewBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("PointSymbolizer Preview"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *previewSizer = new wxStaticBoxSizer(previewBox, wxVERTICAL);
+  previewBoxSizer->Add(previewSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  DrawPreview(500, 300);
+  SymbolizerPreview *previewCtrl =
+    new SymbolizerPreview(this, panel, ID_SYMBOLIZER_PREVIEW,
+                          PreviewBackBitmap, wxSize(500, 300));
+  previewSizer->Add(previewCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// Background selector
+  wxBoxSizer *extraSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(extraSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxString back[3];
+  back[0] = wxT("&Checked");
+  back[1] = wxT("&White");
+  back[2] = wxT("&Black");
+  wxRadioBox *backBox = new wxRadioBox(panel, ID_SYMBOLIZER_BACKGROUND,
+                                       wxT("&Background"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 3,
+                                       back, 1,
+                                       wxRA_SPECIFY_COLS);
+  extraSizer->Add(backBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  backBox->SetSelection(0);
+// Crosshair selector
+  wxString crosshair[2];
+  crosshair[0] = wxT("&Show");
+  crosshair[1] = wxT("&Hide");
+  wxRadioBox *crossBox = new wxRadioBox(panel, ID_SYMBOLIZER_CROSSHAIR,
+                                        wxT("&Crosshair"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 2,
+                                        crosshair, 1,
+                                        wxRA_SPECIFY_COLS);
+  extraSizer->Add(crossBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  crossBox->SetSelection(0);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_BACKGROUND, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdBackgroundChanged);
+  Connect(ID_SYMBOLIZER_CROSSHAIR, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimplePointSymbolizerDialog::OnCmdCrosshairChanged);
+  return panel;
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdBackgroundChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Preview Background selection changed
+//
+  wxRadioBox *backCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_BACKGROUND);
+  switch (backCtrl->GetSelection())
+    {
+      case 1:
+        PreviewBackground = GUI_PREVIEW_BACKGROUND_WHITE;
+        break;
+      case 2:
+        PreviewBackground = GUI_PREVIEW_BACKGROUND_BLACK;
+        break;
+      default:
+        PreviewBackground = GUI_PREVIEW_BACKGROUND_CHECKED;
+        break;
+    };
+  UpdatePreviewPage();
+}
+
+void SimplePointSymbolizerDialog::
+OnCmdCrosshairChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Crosshair selection changed
+//
+  wxRadioBox *crossCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_CROSSHAIR);
+  switch (crossCtrl->GetSelection())
+    {
+      case 1:
+        Crosshair = false;
+        break;
+      default:
+        Crosshair = true;
+        break;
+    };
+  UpdatePreviewPage();
+}
+
+void SimplePointSymbolizerDialog::DrawPreview(int horz, int vert)
+{
+//
+// drawing a Symbolizer Preview
+//
+  PreviewBackBitmap.Create(horz, vert);
+  wxMemoryDC dc(PreviewBackBitmap);
+//
+// background filling
+//
+  wxImage img(24, 24);
+  for (int y = 0; y < 24; y++)
+    {
+      // creating a checked background
+      for (int x = 0; x < 24; x++)
+        {
+          if (y < 12)
+            {
+              if (x < 12)
+                img.SetRGB(x, y, 176, 176, 176);
+              else
+                img.SetRGB(x, y, 208, 208, 208);
+          } else
+            {
+              if (x < 12)
+                img.SetRGB(x, y, 208, 208, 208);
+              else
+                img.SetRGB(x, y, 176, 176, 176);
+            }
+        }
+    }
+  wxBrush stipple(img);
+  dc.SetBrush(stipple);
+  dc.DrawRectangle(0, 0, horz, vert);
+}
+
+void SimplePointSymbolizerDialog::CreateButtons()
+{
+// 
+// adding the common Buttons
+//
+  wxBoxSizer *topSizer = (wxBoxSizer *) (this->GetSizer());
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  topSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *insert =
+    new wxButton(this, ID_SYMBOLIZER_INSERT, wxT("&Insert into DBMS"));
+  btnBox->Add(insert, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *exp =
+    new wxButton(this, ID_SYMBOLIZER_EXPORT, wxT("&Export to file"));
+  btnBox->Add(exp, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *copy = new wxButton(this, ID_SYMBOLIZER_COPY, wxT("&Copy"));
+  btnBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+}
+
+bool SimplePointSymbolizerDialog::FinalValidityCheck()
+{
+//
+// last check before generating the SLD/SE Style
+//
+  if (Name.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the PointSymbolizer NAME !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  if (Title.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some PointSymbolizer TITLE is warmly suggested\n\n");
+      msg += wxT("Do you really confirm leaving an empty (undefined) Title ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  if (Abstract.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some PointSymbolizer ABSTRACT is warmly suggested\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an empty (undefined) Abstract ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  return true;
+}
+
+bool SimplePointSymbolizerDialog::RetrieveMainPage()
+{
+//
+// retrieving params from the MAIN page
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  Name = nameCtrl->GetValue();
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  Title = titleCtrl->GetValue();
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  Abstract = absCtrl->GetValue();
+  if (MinScale == true)
+    {
+      wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+      wxString value = minCtrl->GetValue();
+      if (value.ToDouble(&MinScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MinScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MaxScale == true)
+    {
+      wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+      wxString value = maxCtrl->GetValue();
+      if (value.ToDouble(&MaxScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MaxScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MinScale == true && MaxScale == true)
+    {
+      if (MinScaleDenominator >= MaxScaleDenominator)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE is always expected to be greater than MIN_SCALE !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  return true;
+}
+
+void SimplePointSymbolizerDialog::UpdateMainPage()
+{
+//
+// updating the MAIN page
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  nameCtrl->SetValue(Name);
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  titleCtrl->SetValue(Title);
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  absCtrl->SetValue(Abstract);
+  wxRadioBox *uomBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_UOM);
+  switch (Uom)
+    {
+      case GUI_UOM_METRE:
+        uomBox->SetSelection(1);
+        break;
+      case GUI_UOM_INCH:
+        uomBox->SetSelection(2);
+        break;
+      default:
+        uomBox->SetSelection(0);
+        break;
+    };
+  wxRadioBox *rangeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  if (MinScale != true && MaxScale != true)
+    rangeBox->SetSelection(0);
+  else if (MinScale == true && MaxScale != true)
+    rangeBox->SetSelection(1);
+  else if (MinScale != true && MaxScale == true)
+    rangeBox->SetSelection(2);
+  else
+    rangeBox->SetSelection(3);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  char dummy[64];
+  wxString str;
+  if (MinScale == true)
+    {
+      sprintf(dummy, "%1.2f", MinScaleDenominator);
+      str = wxString::FromUTF8(dummy);
+      minCtrl->SetValue(str);
+      minCtrl->Enable(true);
+  } else
+    {
+      str = wxT("0.0");
+      minCtrl->SetValue(str);
+      minCtrl->Enable(false);
+    }
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  if (MaxScale == true)
+    {
+      sprintf(dummy, "%1.2f", MaxScaleDenominator);
+      str = wxString::FromUTF8(dummy);
+      maxCtrl->SetValue(str);
+      maxCtrl->Enable(true);
+  } else
+    {
+      str = wxT("+Infinite");
+      maxCtrl->SetValue(str);
+      maxCtrl->Enable(false);
+    }
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_TYPE);
+  switch (HasGraphic)
+    {
+      case false:
+        typeBox->SetSelection(1);
+        break;
+      default:
+        typeBox->SetSelection(0);
+        break;
+    };
+}
+
+bool SimplePointSymbolizerDialog::RetrievePositionPage(bool check)
+{
+//
+// retrieving params from the Position page
+//
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_OPACITY);
+  Opacity = opacityCtrl->GetValue() / 100.0;
+  wxTextCtrl *sizeCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_SIZE);
+  wxString value = sizeCtrl->GetValue();
+  if (value.ToDouble(&Size) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("SIZE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (Size < 0.0)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("SIZE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *rotationCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ROTATION);
+  value = rotationCtrl->GetValue();
+  if (value.ToDouble(&Rotation) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("ROTATION isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *anchorXCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ANCHOR_X);
+  value = anchorXCtrl->GetValue();
+  if (value.ToDouble(&AnchorPointX) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("ANCHOR-POINT-X isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (AnchorPointX < 0.0 || AnchorPointX > 1.0)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("ANCHOR-POINT-X must be between 0.0 and 1.0 !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *anchorYCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ANCHOR_Y);
+  value = anchorYCtrl->GetValue();
+  if (value.ToDouble(&AnchorPointY) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("ANCHOR-POINT-Y isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (AnchorPointY < 0.0 || AnchorPointY > 1.0)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("ANCHOR-POINT-Y must be between 0.0 and 1.0 !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *displXCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_DISPLACEMENT_X);
+  value = displXCtrl->GetValue();
+  if (value.ToDouble(&DisplacementX) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("DISPLACEMENT-X isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxTextCtrl *displYCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_DISPLACEMENT_Y);
+  value = displYCtrl->GetValue();
+  if (value.ToDouble(&DisplacementY) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("DISPLACEMENT-Y isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  return true;
+}
+
+void SimplePointSymbolizerDialog::UpdatePositionPage()
+{
+//
+// updating the Position page
+//
+  wxSlider *opacityCtrl = (wxSlider *) FindWindow(ID_SYMBOLIZER_OPACITY);
+  opacityCtrl->SetValue(Opacity * 100.0);
+  wxTextCtrl *sizeCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_SIZE);
+  char dummy[64];
+  sprintf(dummy, "%1.2f", Size);
+  wxString str = wxString::FromUTF8(dummy);
+  sizeCtrl->SetValue(str);
+  wxTextCtrl *rotationCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ROTATION);
+  sprintf(dummy, "%1.2f", Rotation);
+  str = wxString::FromUTF8(dummy);
+  rotationCtrl->SetValue(str);
+  wxTextCtrl *anchorXCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ANCHOR_X);
+  sprintf(dummy, "%1.2f", AnchorPointX);
+  str = wxString::FromUTF8(dummy);
+  anchorXCtrl->SetValue(str);
+  wxTextCtrl *anchorYCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ANCHOR_Y);
+  sprintf(dummy, "%1.2f", AnchorPointY);
+  str = wxString::FromUTF8(dummy);
+  anchorYCtrl->SetValue(str);
+  wxTextCtrl *displXCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_DISPLACEMENT_X);
+  sprintf(dummy, "%1.2f", DisplacementX);
+  str = wxString::FromUTF8(dummy);
+  displXCtrl->SetValue(str);
+  wxTextCtrl *displYCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_DISPLACEMENT_Y);
+  sprintf(dummy, "%1.2f", DisplacementY);
+  str = wxString::FromUTF8(dummy);
+  displYCtrl->SetValue(str);
+}
+
+bool SimplePointSymbolizerDialog::RetrieveGraphicPage(bool check)
+{
+//
+// retrieving params from the Graphic page
+//
+  if (HasGraphic == false)
+    return true;
+  int selCount = 0;
+  int selected = -1;
+  for (int i = 0; i < GridCtrl->GetNumberRows(); i++)
+    {
+      if (GridCtrl->IsInSelection(i, 0) == true)
+        {
+          selected = i;
+          selCount++;
+        }
+    }
+  if (selCount < 1)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("You must select an External Graphic resource !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (selCount > 1)
+    {
+      if (check == true)
+        {
+          wxString msg =
+            wxT
+            ("You must select just a single External Graphic resource !!!\n");
+          msg += wxT("Multiple selection is not supported");
+          wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  List->FindByIndex(selected, XLinkHref, MimeType);
+  if (EnableColorReplacement == true)
+    {
+      wxTextCtrl *replacementCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR_REPLACEMENT);
+      wxString color = replacementCtrl->GetValue();
+      if (ColorMapEntry::IsValidColor(color) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("COLOR-REPACEMENT isn't a valid HexRGB color !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      ColorReplacement = color;
+    }
+  return true;
+}
+
+void SimplePointSymbolizerDialog::UpdateGraphicPage()
+{
+//
+// updating the Graphic page
+//
+  wxCheckBox *enableReplacement =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_ENABLE_COLOR_REPLACEMENT);
+  wxTextCtrl *replacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR_REPLACEMENT);
+  wxTextCtrl *sampleReplacementCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_COLOR_REPLACEMENT_HEX);
+  wxButton *pick =
+    (wxButton *) FindWindow(ID_SYMBOLIZER_REPLACEMENT_PICKER_BTN);
+  int sel = List->FindByXLinkHref(XLinkHref);
+  if (sel >= 0)
+    GridCtrl->SelectRow(sel);
+  if (EnableColorReplacement == true)
+    {
+      wxColour color = wxNullColour;
+      ColorMapEntry::GetWxColor(ColorReplacement, color);
+      if (color.IsOk() == true)
+        {
+          char hex[16];
+          sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                  color.Blue());
+          wxString str = wxString::FromUTF8(hex);
+          replacementCtrl->SetValue(str);
+        }
+    }
+  wxCheckBox *rescaleCtrl =
+    (wxCheckBox *) FindWindow(ID_ONLY_RESCALE_SVG_SYMBOLS);
+  if (OnlyRescaleSVG == true)
+    rescaleCtrl->SetValue(true);
+  else
+    rescaleCtrl->SetValue(false);
+  if (HasGraphic == true)
+    {
+      GridCtrl->Enable(true);
+      enableReplacement->Enable(true);
+      if (EnableColorReplacement == true)
+        {
+          replacementCtrl->Enable(true);
+          pick->Enable(true);
+      } else
+        {
+          replacementCtrl->Enable(false);
+          pick->Enable(false);
+        }
+      rescaleCtrl->Enable(true);
+  } else
+    {
+      GridCtrl->Enable(false);
+      enableReplacement->Enable(false);
+      replacementCtrl->Enable(false);
+      pick->Enable(false);
+      rescaleCtrl->Enable(false);
+    }
+}
+
+bool SimplePointSymbolizerDialog::DoParseDashArray(wxString & str)
+{
+//
+// attempting to parse a Stroke DashArray string
+//
+  StrokeDashCount = 0;
+  if (StrokeDashArray != NULL)
+    delete[]StrokeDashArray;
+  StrokeDashArray = NULL;
+  if (str.Len() == 0)
+    return true;
+  int count = 0;
+  double interval;
+  wxStringTokenizer tkz(str, wxT(","));
+  while (tkz.HasMoreTokens())
+    {
+      wxString token = tkz.GetNextToken();
+      if (token.ToDouble(&interval) != true)
+        return false;
+      if (interval <= 0.0)
+        return false;
+      count++;
+    }
+  if (count == 0)
+    return true;
+  double *array;
+  StrokeDashCount = count;
+  StrokeDashArray = new double[StrokeDashCount];
+  array = StrokeDashArray;
+  count = 0;
+  wxStringTokenizer tkz2(str, wxT(","));
+  while (tkz2.HasMoreTokens())
+    {
+      wxString token = tkz2.GetNextToken();
+      token.ToDouble(&interval);
+      *(array + count++) = interval;
+    }
+  return true;
+}
+
+void SimplePointSymbolizerDialog::NormalizedDashArray(wxString & str,
+                                                      char delimiter)
+{
+//
+// creating a normalized DashArray string
+//
+  int count;
+  double *array;
+  count = StrokeDashCount;
+  array = StrokeDashArray;
+  str = wxT("");
+  if (count == 0)
+    return;
+  for (int i = 0; i < count; i++)
+    {
+      char dummy[64];
+      if (i == 0)
+        sprintf(dummy, "%1.2f", *(array + i));
+      else if (delimiter == ' ')
+        sprintf(dummy, " %1.2f", *(array + i));
+      else
+        sprintf(dummy, "%c %1.2f", delimiter, *(array + i));
+      str += wxString::FromUTF8(dummy);
+    }
+}
+
+bool SimplePointSymbolizerDialog::RetrieveMarkPage(bool check)
+{
+//
+// retrieving params from the Mark page
+//
+  if (HasGraphic == true)
+    return true;
+  if (EnableFill == false && EnableStroke == false)
+    {
+      wxMessageBox(wxT
+                   ("Effectless Mark: both Fill and Stroke are disabled !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  if (EnableFill == true)
+    {
+      wxTextCtrl *colorCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_COLOR);
+      wxString color = colorCtrl->GetValue();
+      if (ColorMapEntry::IsValidColor(color) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("FILL-COLOR isn't a valid HexRGB color !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      FillColor = color;
+    }
+  if (EnableStroke == true)
+    {
+      wxTextCtrl *colorCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE_COLOR);
+      wxString color = colorCtrl->GetValue();
+      if (ColorMapEntry::IsValidColor(color) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-COLOR isn't a valid HexRGB color !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      StrokeColor = color;
+      wxTextCtrl *widthCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE_WIDTH);
+      wxString value = widthCtrl->GetValue();
+      if (value.ToDouble(&StrokeWidth) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-WIDTH isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (StrokeWidth <= 0.0)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-WIDTH must be a positive number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      wxTextCtrl *dashArrayCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE_DASHARRAY);
+      value = dashArrayCtrl->GetValue();
+      if (DoParseDashArray(value) == false)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("STROKE-DASH-ARRAY: invalid expression !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+      } else
+        {
+          NormalizedDashArray(value, 0);
+          dashArrayCtrl->SetValue(value);
+        }
+      if (StrokeDashCount == 0)
+        StrokeDashOffset = 0.0;
+      else
+        {
+          wxTextCtrl *offsetCtrl =
+            (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE_DASHOFFSET);
+          wxString value = offsetCtrl->GetValue();
+          if (value.ToDouble(&StrokeDashOffset) != true)
+            {
+              if (check == true)
+                {
+                  wxMessageBox(wxT
+                               ("STROKE-DASH-OFFSET isn't a valid decimal number !!!"),
+                               wxT("spatialite_gui"), wxOK | wxICON_WARNING,
+                               this);
+                  return false;
+                }
+            }
+        }
+    }
+  return true;
+}
+
+void SimplePointSymbolizerDialog::UpdateMarkPage()
+{
+//
+// updating the Mark page
+//
+  wxRadioBox *markCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MARK);
+  switch (WellKnownMark)
+    {
+      case RL2_GRAPHIC_MARK_CIRCLE:
+        markCtrl->SetSelection(1);
+        break;
+      case RL2_GRAPHIC_MARK_TRIANGLE:
+        markCtrl->SetSelection(2);
+        break;
+      case RL2_GRAPHIC_MARK_STAR:
+        markCtrl->SetSelection(3);
+        break;
+      case RL2_GRAPHIC_MARK_CROSS:
+        markCtrl->SetSelection(4);
+        break;
+      case RL2_GRAPHIC_MARK_X:
+        markCtrl->SetSelection(5);
+        break;
+      default:
+        markCtrl->SetSelection(0);
+        break;
+    };
+  wxCheckBox *enableFillBox =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_FILL_ENABLE);
+  if (EnableFill == true)
+    enableFillBox->SetValue(true);
+  else
+    enableFillBox->SetValue(false);
+  wxTextCtrl *colorFillCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_COLOR);
+  wxTextCtrl *sampleFillCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_PICKER_HEX);
+  wxButton *pickFill = (wxButton *) FindWindow(ID_SYMBOLIZER_FILL_PICKER_BTN);
+  if (EnableFill == true)
+    {
+      wxColour color = wxNullColour;
+      ColorMapEntry::GetWxColor(FillColor, color);
+      if (color.IsOk() == true)
+        {
+          char hex[16];
+          sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                  color.Blue());
+          wxString str = wxString::FromUTF8(hex);
+          colorFillCtrl->SetValue(str);
+        }
+    }
+  wxCheckBox *enableStrokeBox =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_STROKE_ENABLE);
+  if (EnableStroke == true)
+    enableStrokeBox->SetValue(true);
+  else
+    enableStrokeBox->SetValue(false);
+  wxTextCtrl *colorStrokeCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE_COLOR);
+  wxTextCtrl *sampleStrokeCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_PICKER_HEX);
+  wxButton *pickStroke =
+    (wxButton *) FindWindow(ID_SYMBOLIZER_STROKE_PICKER_BTN);
+  if (EnableStroke == true)
+    {
+      wxColour color = wxNullColour;
+      ColorMapEntry::GetWxColor(StrokeColor, color);
+      if (color.IsOk() == true)
+        {
+          char hex[16];
+          sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(),
+                  color.Blue());
+          wxString str = wxString::FromUTF8(hex);
+          colorStrokeCtrl->SetValue(str);
+        }
+    }
+  wxTextCtrl *widthCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE_WIDTH);
+  char dummy[64];
+  sprintf(dummy, "%1.2f", StrokeWidth);
+  wxString str = wxString::FromUTF8(dummy);
+  widthCtrl->SetValue(str);
+  wxRadioBox *lineJoinCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE_LINEJOIN);
+  switch (StrokeLineJoin)
+    {
+      case RL2_PEN_JOIN_MITER:
+        lineJoinCtrl->SetSelection(0);
+        break;
+      case RL2_PEN_JOIN_BEVEL:
+        lineJoinCtrl->SetSelection(2);
+        break;
+      default:
+        lineJoinCtrl->SetSelection(1);
+        break;
+    };
+  wxRadioBox *lineCapCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_STROKE_LINECAP);
+  switch (StrokeLineCap)
+    {
+      case RL2_PEN_CAP_BUTT:
+        lineCapCtrl->SetSelection(0);
+        break;
+      case RL2_PEN_CAP_SQUARE:
+        lineCapCtrl->SetSelection(2);
+        break;
+      default:
+        lineCapCtrl->SetSelection(1);
+        break;
+    };
+  wxTextCtrl *dashArrayCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE_DASHARRAY);
+  wxString value;
+  NormalizedDashArray(value, 0);
+  dashArrayCtrl->SetValue(value);
+  wxTextCtrl *offsetCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_STROKE_DASHOFFSET);
+  if (StrokeDashCount == 0)
+    offsetCtrl->SetValue(wxT("0.0"));
+  else
+    {
+      char dummy[64];
+      sprintf(dummy, "%1.2f", StrokeDashOffset);
+      wxString str = wxString::FromUTF8(dummy);
+      offsetCtrl->SetValue(str);
+    }
+  if (HasGraphic == false)
+    {
+      markCtrl->Enable(true);
+      enableFillBox->Enable(true);
+      if (EnableFill == false)
+        {
+          colorFillCtrl->Enable(false);
+          sampleFillCtrl->Enable(false);
+          pickFill->Enable(false);
+      } else
+        {
+          colorFillCtrl->Enable(true);
+          sampleFillCtrl->Enable(true);
+          pickFill->Enable(true);
+        }
+      enableStrokeBox->Enable(true);
+      if (EnableStroke == false)
+        {
+          colorStrokeCtrl->Enable(false);
+          sampleStrokeCtrl->Enable(false);
+          pickStroke->Enable(false);
+          widthCtrl->Enable(false);
+          lineJoinCtrl->Enable(false);
+          lineCapCtrl->Enable(false);
+          dashArrayCtrl->Enable(false);
+          offsetCtrl->Enable(false);
+      } else
+        {
+          colorStrokeCtrl->Enable(true);
+          sampleStrokeCtrl->Enable(true);
+          pickStroke->Enable(true);
+          widthCtrl->Enable(true);
+          lineJoinCtrl->Enable(true);
+          lineCapCtrl->Enable(true);
+          dashArrayCtrl->Enable(true);
+          offsetCtrl->Enable(true);
+        }
+  } else
+    {
+      markCtrl->Enable(false);
+      enableFillBox->Enable(false);
+      colorFillCtrl->Enable(false);
+      sampleFillCtrl->Enable(false);
+      pickFill->Enable(false);
+      enableStrokeBox->Enable(false);
+      colorStrokeCtrl->Enable(false);
+      sampleStrokeCtrl->Enable(false);
+      pickStroke->Enable(false);
+      widthCtrl->Enable(false);
+      lineJoinCtrl->Enable(false);
+      lineCapCtrl->Enable(false);
+      dashArrayCtrl->Enable(false);
+      offsetCtrl->Enable(false);
+    }
+}
+
+bool SimplePointSymbolizerDialog::RetrievePreviewPage()
+{
+//
+// retrieving params from the PREVIEW page
+//
+  return true;
+}
+
+void SimplePointSymbolizerDialog::UpdatePreviewPage()
+{
+//
+// updating the PREVIEW page
+//
+  wxRadioBox *backCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_BACKGROUND);
+  switch (PreviewBackground)
+    {
+      case GUI_PREVIEW_BACKGROUND_WHITE:
+        backCtrl->SetSelection(1);
+        break;
+      case GUI_PREVIEW_BACKGROUND_BLACK:
+        backCtrl->SetSelection(2);
+        break;
+      default:
+        backCtrl->SetSelection(0);
+        break;
+    };
+  wxRadioBox *crossCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_CROSSHAIR);
+  if (Crosshair == false)
+    crossCtrl->SetSelection(1);
+  else
+    crossCtrl->SetSelection(0);
+  rl2GraphicsContextPtr ctx = NULL;
+  ctx = rl2_graph_create_context(500, 300);
+  if (ctx == NULL)
+    return;
+// transparent background initialization
+  rl2_graph_set_brush(ctx, 255, 255, 255, 0);
+  rl2_graph_draw_rectangle(ctx, -1, -1, 501, 301);
+
+  rl2GraphicsPatternPtr pattern = NULL;
+  if (HasGraphic == true)
+    {
+      // Graphic Symbol
+      if (MimeType.Cmp(wxT("image/svg+xml")) == 0)
+        {
+          // SVG symbol
+          pattern =
+            rl2_create_pattern_from_external_svg(MainFrame->GetSqlite(),
+                                                 XLinkHref.ToUTF8(), Size);
+      } else
+        {
+          // bitmap symbol
+          pattern =
+            rl2_create_pattern_from_external_graphic(MainFrame->GetSqlite(),
+                                                     XLinkHref.ToUTF8(), 0);
+        }
+      if (pattern != NULL)
+        {
+          if (EnableColorReplacement)
+            {
+              // attempting to recolor the External Graphic resource
+              wxColour color = wxNullColour;
+              ColorMapEntry::GetWxColor(ColorReplacement, color);
+              rl2_graph_pattern_recolor(pattern, color.Red(), color.Green(),
+                                        color.Blue());
+            }
+          if (Opacity < 1.0)
+            {
+              // setting up the required transparency
+              double aleph = 255.0 * Opacity;
+              if (aleph < 0.0)
+                aleph = 0.0;
+              if (aleph > 255.0)
+                aleph = 255.0;
+              unsigned char alpha = aleph;
+              rl2_graph_pattern_transparency(pattern, alpha);
+            }
+          unsigned int width;
+          unsigned int height;
+          rl2_graph_get_pattern_size(pattern, &width, &height);
+          double out_width = width;
+          double out_height = height;
+          if (OnlyRescaleSVG == false)
+            {
+              double scale;
+              if (width > height)
+                scale = Size / (double) width;
+              else
+                scale = Size / (double) height;
+              out_width = (double) width *scale;
+              out_height = (double) height *scale;
+            }
+          rl2_graph_draw_graphic_symbol(ctx, pattern, out_width, out_height,
+                                        250.0 + DisplacementX,
+                                        150.0 - DisplacementY, Rotation,
+                                        AnchorPointX, AnchorPointY);
+          rl2_graph_destroy_pattern(pattern);
+        }
+  } else
+    {
+      // Mark Symbol
+      if (EnableFill == true)
+        {
+          // preparing a Color-based Brush
+          double aleph = 255.0 * Opacity;
+          if (aleph < 0.0)
+            aleph = 0.0;
+          if (aleph > 255.0)
+            aleph = 255.0;
+          unsigned char alpha = aleph;
+          wxColour color = wxNullColour;
+          ColorMapEntry::GetWxColor(FillColor, color);
+          rl2_graph_set_brush(ctx, color.Red(), color.Green(), color.Blue(),
+                              alpha);
+        }
+      if (EnableStroke == true)
+        {
+          // preparing a Color-based Pen
+          double aleph = 255.0 * Opacity;
+          if (aleph < 0.0)
+            aleph = 0.0;
+          if (aleph > 255.0)
+            aleph = 255.0;
+          unsigned char alpha = aleph;
+          wxColour color = wxNullColour;
+          ColorMapEntry::GetWxColor(StrokeColor, color);
+          if (StrokeDashCount == 0)
+            rl2_graph_set_solid_pen(ctx, color.Red(), color.Green(),
+                                    color.Blue(), alpha, StrokeWidth,
+                                    StrokeLineCap, StrokeLineJoin);
+          else
+            rl2_graph_set_dashed_pen(ctx, color.Red(), color.Green(),
+                                     color.Blue(), alpha, StrokeWidth,
+                                     StrokeLineCap, StrokeLineJoin,
+                                     StrokeDashCount, StrokeDashArray,
+                                     StrokeDashOffset);
+        }
+      // drawing the Mark Symbol
+      int fill = 1;
+      int stroke = 1;
+      if (EnableFill == false)
+        fill = 0;
+      if (EnableStroke == false)
+        stroke = 0;
+      rl2_graph_draw_mark_symbol(ctx, WellKnownMark, Size,
+                                 250.0 + DisplacementX, 150.0 - DisplacementY,
+                                 Rotation, AnchorPointX, AnchorPointY, fill,
+                                 stroke);
+    }
+
+// creating the RGB and Alpha arrays
+  int half_transparency = 0;
+  unsigned char *rgb_array = rl2_graph_get_context_rgb_array(ctx);
+  unsigned char *alpha_array =
+    rl2_graph_get_context_alpha_array(ctx, &half_transparency);
+  rl2_graph_destroy_context(ctx);
+  if (rgb_array == NULL || alpha_array == NULL)
+    {
+      if (rgb_array != NULL)
+        free(rgb_array);
+      if (alpha_array != NULL)
+        free(alpha_array);
+      return;
+    }
+// creating the Preview from RGB and Alpha arrays
+  wxImage img(500, 300);
+  img.SetData(rgb_array);
+  img.SetAlpha(alpha_array);
+  wxBitmap bmp(img);
+  wxBitmap bmp2;
+  wxBrush brush;
+  wxMemoryDC dc;
+  wxBitmap white = wxBitmap(500, 300);
+  wxBitmap black = wxBitmap(500, 300);
+  switch (PreviewBackground)
+    {
+      case GUI_PREVIEW_BACKGROUND_WHITE:
+        dc.SelectObject(white);
+        brush = wxBrush(wxColour(255, 255, 255));
+        dc.SetBrush(brush);
+        dc.DrawRectangle(0, 0, 500, 300);
+        dc.SelectObject(wxNullBitmap);
+        bmp2 =
+          white.GetSubBitmap(wxRect(0, 0, white.GetWidth(), white.GetHeight()));
+        break;
+      case GUI_PREVIEW_BACKGROUND_BLACK:
+        dc.SelectObject(black);
+        brush = wxBrush(wxColour(0, 0, 0));
+        dc.SetBrush(brush);
+        dc.DrawRectangle(0, 0, 500, 300);
+        dc.SelectObject(wxNullBitmap);
+        bmp2 =
+          black.GetSubBitmap(wxRect(0, 0, black.GetWidth(), black.GetHeight()));
+        break;
+      default:
+        bmp2 =
+          PreviewBackBitmap.GetSubBitmap(wxRect
+                                         (0, 0, PreviewBackBitmap.GetWidth(),
+                                          PreviewBackBitmap.GetHeight()));
+        break;
+    };
+// printing the Preview over the currently selected background
+  dc.SelectObject(bmp2);
+  dc.DrawBitmap(bmp, 0, 0, true);
+  if (Crosshair == true)
+    {
+      // printing the Crosshair over the preview
+      wxColour color = wxColour(255, 255, 255);
+      if (PreviewBackground == GUI_PREVIEW_BACKGROUND_BLACK)
+        color = wxColour(0, 0, 0);
+      dc.SetPen(wxPen(color, 3));
+      dc.DrawLine(250 + DisplacementX, 0, 250 + DisplacementX, 300);
+      dc.DrawLine(0, 150 - DisplacementY, 500, 150 - DisplacementY);
+      color = wxColour(0, 0, 0);
+      if (PreviewBackground == GUI_PREVIEW_BACKGROUND_BLACK)
+        color = wxColour(255, 255, 255);
+      dc.SetPen(wxPen(color, 1));
+      dc.DrawLine(250 + DisplacementX, 0, 250 + DisplacementX, 300);
+      dc.DrawLine(0, 150 - DisplacementY, 500, 150 - DisplacementY);
+      color = wxColour(0, 0, 0);
+      if (PreviewBackground == GUI_PREVIEW_BACKGROUND_BLACK)
+        color = wxColour(255, 255, 255);
+      dc.SetPen(wxPen(color, 5));
+      dc.DrawLine(248, 150, 252, 150);
+      dc.DrawLine(250, 148, 250, 152);
+      color = wxColour(255, 0, 0);
+      dc.SetPen(wxPen(color, 3));
+      dc.DrawLine(249, 150, 251, 150);
+      dc.DrawLine(250, 149, 250, 151);
+    }
+  dc.SelectObject(wxNullBitmap);
+// updating the GUI Preview
+  SymbolizerPreview *previewCtrl =
+    (SymbolizerPreview *) FindWindow(ID_SYMBOLIZER_PREVIEW);
+  previewCtrl->SetBitmap(bmp2);
+}
+
+void SimplePointSymbolizerDialog::OnPageChanging(wxNotebookEvent & event)
+{
+//
+// TAB/PAGE selection changing
+//
+  bool ret;
+  switch (event.GetOldSelection())
+    {
+      case 0:
+        ret = RetrieveMainPage();
+        break;
+      case 1:
+        ret = RetrievePositionPage();
+        break;
+      case 2:
+        ret = RetrieveGraphicPage();
+        break;
+      case 3:
+        ret = RetrieveMarkPage();
+        break;
+      case 4:
+        ret = RetrievePreviewPage();
+        break;
+    };
+  if (ret != true)
+    event.Veto();
+}
+
+void SimplePointSymbolizerDialog::OnPageChanged(wxNotebookEvent & event)
+{
+//
+// TAB/PAGE selection changed
+//
+  switch (event.GetSelection())
+    {
+      case 0:
+        UpdateMainPage();
+        break;
+      case 1:
+        UpdatePositionPage();
+        break;
+      case 2:
+        UpdateGraphicPage();
+        break;
+      case 3:
+        UpdateMarkPage();
+        break;
+      case 4:
+        UpdatePreviewPage();
+        break;
+    };
+}
+
+char *SimplePointSymbolizerDialog::DoCreateFeatureTypeXML()
+{
+//
+// creating the SLD/SE (XML) code - Feature Type
+//
+  char *str;
+  const char *cstr;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<FeatureTypeStyle version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Rule>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (MinScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MinScaleDenominator>%1.2f</MinScaleDenominator>\r\n", prev,
+         MinScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MaxScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MaxScaleDenominator>%1.2f</MaxScaleDenominator>\r\n", prev,
+         MaxScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  switch (Uom)
+    {
+      case GUI_UOM_METRE:
+        cstr = "http://www.opengeospatial.org/se/units/metre";
+        break;
+      case GUI_UOM_INCH:
+        cstr = "http://www.opengeospatial.org/se/units/inch";
+        break;
+      default:
+        cstr = "http://www.opengeospatial.org/se/units/pixel";
+        break;
+    };
+  xml = sqlite3_mprintf("%s\t\t<PointSymbolizer uom=\"%s\">\r\n", prev, cstr);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<Graphic>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (HasGraphic == true)
+    {
+      // graphic symbol
+      xml = sqlite3_mprintf("%s\t\t\t\t<ExternalGraphic>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(XLinkHref.ToUTF8()) + 1];
+      strcpy(str, XLinkHref.ToUTF8());
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t\t<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\" />\r\n",
+         prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(MimeType.ToUTF8()) + 1];
+      strcpy(str, MimeType.ToUTF8());
+      xml = sqlite3_mprintf("%s\t\t\t\t\t<Format>%s</Format>\r\n", prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      if (EnableColorReplacement == true)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t<ColorReplacement>\r\n\t\t\t\t\t\t<Recode fallbackValue=\"#000000\">\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t<LookupValue>ExternalGraphic</LookupValue>\r\n\t\t\t\t\t\t\t<MapItem>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(ColorReplacement.ToUTF8()) + 1];
+          strcpy(str, ColorReplacement.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t\t<Data>1</Data>\r\n\t\t\t\t\t\t\t\t<Value>%s</Value>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t\t</MapItem>\r\n\t\t\t\t\t\t</Recode>\r\n\t\t\t\t\t</ColorReplacement>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t\t\t</ExternalGraphic>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+  } else
+    {
+      // mark symbol
+      xml = sqlite3_mprintf("%s\t\t\t\t<Mark>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      switch (WellKnownMark)
+        {
+          case RL2_GRAPHIC_MARK_CIRCLE:
+            cstr = "circle";
+            break;
+          case RL2_GRAPHIC_MARK_TRIANGLE:
+            cstr = "triangle";
+            break;
+          case RL2_GRAPHIC_MARK_STAR:
+            cstr = "star";
+            break;
+          case RL2_GRAPHIC_MARK_CROSS:
+            cstr = "cross";
+            break;
+          case RL2_GRAPHIC_MARK_X:
+            cstr = "x";
+            break;
+          default:
+            cstr = "square";
+            break;
+        };
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t\t<WellKnownName>%s</WellKnownName>\r\n",
+                        prev, cstr);
+      sqlite3_free(prev);
+      prev = xml;
+      if (EnableFill == true)
+        {
+          // Mark Fill
+          xml = sqlite3_mprintf("%s\t\t\t\t\t<Fill>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(FillColor.ToUTF8()) + 1];
+          strcpy(str, FillColor.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t<SvgParameter name=\"fill\">%s</SvgParameter>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          xml = sqlite3_mprintf("%s\t\t\t\t\t</Fill>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (EnableStroke == true)
+        {
+          // Mark Stroke
+          xml = sqlite3_mprintf("%s\t\t\t\t\t<Stroke>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(StrokeColor.ToUTF8()) + 1];
+          strcpy(str, StrokeColor.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t<SvgParameter name=\"stroke\">%s</SvgParameter>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t<SvgParameter name=\"stroke-width\">%1.2f</SvgParameter>\r\n",
+             prev, StrokeWidth);
+          sqlite3_free(prev);
+          prev = xml;
+          switch (StrokeLineJoin)
+            {
+              case RL2_PEN_JOIN_MITER:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t\t\t<SvgParameter name=\"stroke-linejoin\">mitre</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+              case RL2_PEN_JOIN_BEVEL:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t\t\t<SvgParameter name=\"stroke-linejoin\">bevel</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+              default:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t\t\t<SvgParameter name=\"stroke-linejoin\">round</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+            };
+          switch (StrokeLineCap)
+            {
+              case RL2_PEN_CAP_BUTT:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t\t\t<SvgParameter name=\"stroke-linecap\">butt</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+              case RL2_PEN_CAP_SQUARE:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t\t\t<SvgParameter name=\"stroke-linecap\">square</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+              default:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t\t\t<SvgParameter name=\"stroke-linecap\">round</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+            };
+          if (StrokeDashCount > 0 && StrokeDashArray != NULL)
+            {
+              wxString dash;
+              NormalizedDashArray(dash, ' ');
+              str = new char[strlen(dash.ToUTF8()) + 1];
+              strcpy(str, dash.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t\t\t<SvgParameter name=\"stroke-dasharray\">%s</SvgParameter>\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              if (StrokeDashOffset != 0.0)
+                {
+                  xml =
+                    sqlite3_mprintf
+                    ("%s\t\t\t\t\t\t<SvgParameter name=\"stroke-dashoffset\">%1.2f</SvgParameter>\r\n",
+                     prev, StrokeDashOffset);
+                  sqlite3_free(prev);
+                  prev = xml;
+                }
+            }
+          xml = sqlite3_mprintf("%s\t\t\t\t\t</Stroke>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t\t\t</Mark>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (Opacity != 1.0)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MimeType.Cmp(wxT("image/svg+xml")) == 0 || HasGraphic == false)
+    {
+      xml = sqlite3_mprintf("%s\t\t\t\t<Size>%1.2f</Size>\r\n", prev, Size);
+      sqlite3_free(prev);
+      prev = xml;
+  } else if (OnlyRescaleSVG == false)
+    {
+      xml = sqlite3_mprintf("%s\t\t\t\t<Size>%1.2f</Size>\r\n", prev, Size);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (Rotation != 0.0)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t<Rotation>%1.2f</Rotation>\r\n", prev, Rotation);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (AnchorPointX != 0.5 || AnchorPointY != 0.5)
+    {
+      xml = sqlite3_mprintf("%s\t\t\t\t<AnchorPoint>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t\t<AnchorPointX>%1.4f</AnchorPointX>\r\n",
+                        prev, AnchorPointX);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t\t<AnchorPointY>%1.4f</AnchorPointY>\r\n",
+                        prev, AnchorPointY);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t\t\t</AnchorPoint>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (DisplacementX != 0.0 || DisplacementY != 0.0)
+    {
+      xml = sqlite3_mprintf("%s\t\t\t\t<Displacement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t\t<DisplacementX>%1.4f</DisplacementX>\r\n",
+                        prev, DisplacementX);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t\t<DisplacementY>%1.4f</DisplacementY>\r\n",
+                        prev, DisplacementY);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t\t\t</Displacement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t\t</Graphic>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t</PointSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</Rule>\r\n</FeatureTypeStyle>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+char *SimplePointSymbolizerDialog::DoCreateSymbolizerXML()
+{
+//
+// creating the SLD/SE (XML) code - PointSymbolizer
+//
+  char *str;
+  const char *cstr;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<PointSymbolizer version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/Symbolizer.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  switch (Uom)
+    {
+      case GUI_UOM_METRE:
+        cstr = "http://www.opengeospatial.org/se/units/metre";
+        break;
+      case GUI_UOM_INCH:
+        cstr = "http://www.opengeospatial.org/se/units/inch";
+        break;
+      default:
+        cstr = "http://www.opengeospatial.org/se/units/pixel";
+        break;
+    };
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" uom=\"%s\">\r\n",
+     prev, cstr);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Graphic>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (HasGraphic == true)
+    {
+      // graphic symbol
+      xml = sqlite3_mprintf("%s\t\t<ExternalGraphic>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(XLinkHref.ToUTF8()) + 1];
+      strcpy(str, XLinkHref.ToUTF8());
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\" />\r\n",
+         prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(MimeType.ToUTF8()) + 1];
+      strcpy(str, MimeType.ToUTF8());
+      xml = sqlite3_mprintf("%s\t\t\t<Format>%s</Format>\r\n", prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      if (EnableColorReplacement == true)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t<ColorReplacement>\r\n\t\t\t\t<Recode fallbackValue=\"#000000\">\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t<LookupValue>ExternalGraphic</LookupValue>\r\n\t\t\t\t\t<MapItem>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(ColorReplacement.ToUTF8()) + 1];
+          strcpy(str, ColorReplacement.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t<Data>1</Data>\r\n\t\t\t\t\t\t<Value>%s</Value>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t</MapItem>\r\n\t\t\t\t</Recode>\r\n\t\t\t</ColorReplacement>\r\n",
+             prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t</ExternalGraphic>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+  } else
+    {
+      // mark symbol
+      xml = sqlite3_mprintf("%s\t\t<Mark>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      switch (WellKnownMark)
+        {
+          case RL2_GRAPHIC_MARK_CIRCLE:
+            cstr = "circle";
+            break;
+          case RL2_GRAPHIC_MARK_TRIANGLE:
+            cstr = "triangle";
+            break;
+          case RL2_GRAPHIC_MARK_STAR:
+            cstr = "star";
+            break;
+          case RL2_GRAPHIC_MARK_CROSS:
+            cstr = "cross";
+            break;
+          case RL2_GRAPHIC_MARK_X:
+            cstr = "x";
+            break;
+          default:
+            cstr = "square";
+            break;
+        };
+      xml =
+        sqlite3_mprintf("%s\t\t\t<WellKnownName>%s</WellKnownName>\r\n", prev,
+                        cstr);
+      sqlite3_free(prev);
+      prev = xml;
+      if (EnableFill == true)
+        {
+          // Mark Fill
+          xml = sqlite3_mprintf("%s\t\t\t<Fill>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(FillColor.ToUTF8()) + 1];
+          strcpy(str, FillColor.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"fill\">%s</SvgParameter>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          xml = sqlite3_mprintf("%s\t\t\t</Fill>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (EnableStroke == true)
+        {
+          // Mark Stroke
+          xml = sqlite3_mprintf("%s\t\t\t<Stroke>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+          str = new char[strlen(StrokeColor.ToUTF8()) + 1];
+          strcpy(str, StrokeColor.ToUTF8());
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"stroke\">%s</SvgParameter>\r\n",
+             prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<SvgParameter name=\"stroke-width\">%1.2f</SvgParameter>\r\n",
+             prev, StrokeWidth);
+          sqlite3_free(prev);
+          prev = xml;
+          switch (StrokeLineJoin)
+            {
+              case RL2_PEN_JOIN_MITER:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">mitre</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+              case RL2_PEN_JOIN_BEVEL:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">bevel</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+              default:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t<SvgParameter name=\"stroke-linejoin\">round</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+            };
+          switch (StrokeLineCap)
+            {
+              case RL2_PEN_CAP_BUTT:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">butt</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+              case RL2_PEN_CAP_SQUARE:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">square</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+              default:
+                xml =
+                  sqlite3_mprintf
+                  ("%s\t\t\t\t<SvgParameter name=\"stroke-linecap\">round</SvgParameter>\r\n",
+                   prev);
+                sqlite3_free(prev);
+                prev = xml;
+                break;
+            };
+          if (StrokeDashCount > 0 && StrokeDashArray != NULL)
+            {
+              wxString dash;
+              NormalizedDashArray(dash, ' ');
+              str = new char[strlen(dash.ToUTF8()) + 1];
+              strcpy(str, dash.ToUTF8());
+              xml =
+                sqlite3_mprintf
+                ("%s\t\t\t\t<SvgParameter name=\"stroke-dasharray\">%s</SvgParameter>\r\n",
+                 prev, str);
+              delete[]str;
+              sqlite3_free(prev);
+              prev = xml;
+              if (StrokeDashOffset != 0.0)
+                {
+                  xml =
+                    sqlite3_mprintf
+                    ("%s\t\t\t\t<SvgParameter name=\"stroke-dashoffset\">%1.2f</SvgParameter>\r\n",
+                     prev, StrokeDashOffset);
+                  sqlite3_free(prev);
+                  prev = xml;
+                }
+            }
+          xml = sqlite3_mprintf("%s\t\t\t</Stroke>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t</Mark>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (Opacity != 1.0)
+    {
+      xml =
+        sqlite3_mprintf("%s\t\t<Opacity>%1.2f</Opacity>\r\n", prev, Opacity);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MimeType.Cmp(wxT("image/svg+xml")) == 0 || HasGraphic == false)
+    {
+      xml = sqlite3_mprintf("%s\t\t<Size>%1.2f</Size>\r\n", prev, Size);
+      sqlite3_free(prev);
+      prev = xml;
+  } else if (OnlyRescaleSVG == false)
+    {
+      xml = sqlite3_mprintf("%s\t\t<Size>%1.2f</Size>\r\n", prev, Size);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (Rotation != 0.0)
+    {
+      xml =
+        sqlite3_mprintf("%s\t\t<Rotation>%1.2f</Rotation>\r\n", prev, Rotation);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (AnchorPointX != 0.5 || AnchorPointY != 0.5)
+    {
+      xml = sqlite3_mprintf("%s\t\t<AnchorPoint>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t<AnchorPointX>%1.4f</AnchorPointX>\r\n", prev,
+                        AnchorPointX);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t<AnchorPointY>%1.4f</AnchorPointY>\r\n", prev,
+                        AnchorPointY);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t</AnchorPoint>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (DisplacementX != 0.0 || DisplacementY != 0.0)
+    {
+      xml = sqlite3_mprintf("%s\t\t<Displacement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t<DisplacementX>%1.4f</DisplacementX>\r\n",
+                        prev, DisplacementX);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t<DisplacementY>%1.4f</DisplacementY>\r\n",
+                        prev, DisplacementY);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t</Displacement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t</Graphic>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s</PointSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+void SimplePointSymbolizerDialog::OnInsert(wxCommandEvent & WXUNUSED(event))
+{
+//
+// inserting the VectorSymbolizer into the DBMS
+//
+  switch (GetBookCtrl()->GetSelection())
+    {
+      case 0:
+        RetrieveMainPage();
+        break;
+      case 1:
+        RetrievePositionPage();
+        break;
+      case 2:
+        RetrieveGraphicPage();
+        break;
+      case 3:
+        RetrieveMarkPage();
+        break;
+      case 4:
+        RetrievePreviewPage();
+        break;
+    };
+  if (FinalValidityCheck() == false)
+    {
+      GetBookCtrl()->ChangeSelection(0);
+      return;
+    }
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateFeatureTypeXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  if (MainFrame->DoInsertVectorSymbolizer(xml) == true)
+    wxMessageBox(wxT
+                 ("SLD/SE VectorSymbolizer successfully registered into the DBMS"),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  wxDialog::EndModal(wxID_OK);
+}
+
+void SimplePointSymbolizerDialog::OnExport(wxCommandEvent & WXUNUSED(event))
+{
+//
+// exporting the VectorSymbolizer as an external file
+//
+  int ret;
+  wxString path;
+  wxString lastDir;
+  switch (GetBookCtrl()->GetSelection())
+    {
+      case 0:
+        RetrieveMainPage();
+        break;
+      case 1:
+        RetrievePositionPage();
+        break;
+      case 2:
+        RetrieveGraphicPage();
+        break;
+      case 3:
+        RetrieveMarkPage();
+        break;
+      case 4:
+        RetrievePreviewPage();
+        break;
+    };
+  if (FinalValidityCheck() == false)
+    {
+      GetBookCtrl()->ChangeSelection(0);
+      return;
+    }
+  wxFileDialog fileDialog(this,
+                          wxT("Exporting an SLD/SE PointSymbolizer to a file"),
+                          wxT(""), Name + wxT(".xml"),
+                          wxT("XML Document|*.xml|All files (*.*)|*.*"),
+                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      wxFileName file(fileDialog.GetPath());
+      path = file.GetPath();
+      path += file.GetPathSeparator();
+      path += file.GetName();
+      lastDir = file.GetPath();
+      path = fileDialog.GetPath();
+      FILE *out = fopen(path.ToUTF8(), "wb");
+      if (out == NULL)
+        wxMessageBox(wxT("ERROR: unable to create:\n\n\"") + path + wxT("\""),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else
+        {
+          char *xml;
+          if (MinScale == true || MaxScale == true)
+            xml = DoCreateFeatureTypeXML();
+          else
+            xml = DoCreateSymbolizerXML();
+          fwrite(xml, 1, strlen(xml), out);
+          sqlite3_free(xml);
+          fclose(out);
+          wxMessageBox(wxT
+                       ("SLD/SE PointSymbolizer successfully saved into:\n\n\"")
+                       + path + wxT("\""), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+void SimplePointSymbolizerDialog::OnCopy(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Copying the VectorSymbolizer into the Clipboard 
+//
+  switch (GetBookCtrl()->GetSelection())
+    {
+      case 0:
+        RetrieveMainPage();
+        break;
+      case 1:
+        RetrievePositionPage();
+        break;
+      case 2:
+        RetrieveGraphicPage();
+        break;
+      case 3:
+        RetrieveMarkPage();
+        break;
+      case 4:
+        RetrievePreviewPage();
+        break;
+    };
+  if (FinalValidityCheck() == false)
+    {
+      GetBookCtrl()->ChangeSelection(0);
+      return;
+    }
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateFeatureTypeXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  wxString XMLstring = wxString::FromUTF8(xml);
+  if (wxTheClipboard->Open())
+    {
+      wxTheClipboard->SetData(new wxTextDataObject(XMLstring));
+      wxTheClipboard->Close();
+    }
+}
+
+void SimplePointSymbolizerDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
+
+SimpleTextSymbolizerDialog::SimpleTextSymbolizerDialog()
+{
+// ctor
+  List = NULL;
+}
+
+SimpleTextSymbolizerDialog::~SimpleTextSymbolizerDialog()
+{
+// dtor
+  if (List)
+    delete List;
+}
+
+bool SimpleTextSymbolizerDialog::Create(MyFrame * parent)
+{
+//
+// creating the dialog
+//
+  MainFrame = parent;
+  Uom = GUI_UOM_PIXEL;
+  MinScale = false;
+  MaxScale = false;
+  FontStyle = RL2_FONTSTYLE_NORMAL;
+  FontWeight = RL2_FONTWEIGHT_NORMAL;
+  FontSize = 10.0;
+  PointPlacement = true;
+  Rotation = 0.0;
+  AnchorPointX = 0.5;
+  AnchorPointY = 0.5;
+  DisplacementX = 0.0;
+  DisplacementY = 0.0;
+  PerpendicularOffset = 0.0;
+  IsRepeated = false;
+  InitialGap = 0.0;
+  Gap = 0.0;
+  IsAligned = true;
+  GeneralizeLine = false;
+  HasHalo = false;
+  HaloRadius = 1.0;
+  HaloColor = wxT("#ffffff");
+  HaloOpacity = 1.0;
+  FillColor = wxT("#000000");
+  FillOpacity = 1.0;
+  PreviewBackground = GUI_PREVIEW_BACKGROUND_CHECKED;
+  Crosshair = true;
+  ReferenceLine = true;
+  List = MainFrame->FindTextFont();
+
+  if (wxPropertySheetDialog::Create
+      (parent, wxID_ANY, wxT("Simple Text Symbolizer")) == false)
+    return false;
+  wxBookCtrlBase *book = GetBookCtrl();
+// creates individual panels
+  wxPanel *mainPage = CreateMainPage(book);
+  book->AddPage(mainPage, wxT("General"), true);
+  wxPanel *fontPage = CreateFontPage(book);
+  book->AddPage(fontPage, wxT("Font"), false);
+  wxPanel *placementPage = CreatePlacementPage(book);
+  book->AddPage(placementPage, wxT("Placement"), false);
+  wxPanel *previewPage = CreatePreviewPage(book);
+  book->AddPage(previewPage, wxT("Preview"), false);
+
+  CreateButtons();
+  LayoutDialog();
+// appends event handler for TAB/PAGE changing
+  Connect(wxID_ANY, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING,
+          (wxObjectEventFunction) & SimpleTextSymbolizerDialog::OnPageChanging);
+  Connect(wxID_ANY, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
+          (wxObjectEventFunction) & SimpleTextSymbolizerDialog::OnPageChanged);
+// appends event handler for buttons
+  Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimpleTextSymbolizerDialog::OnQuit);
+  Connect(ID_SYMBOLIZER_INSERT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimpleTextSymbolizerDialog::OnInsert);
+  Connect(ID_SYMBOLIZER_EXPORT, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimpleTextSymbolizerDialog::OnExport);
+  Connect(ID_SYMBOLIZER_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) & SimpleTextSymbolizerDialog::OnCopy);
+// centers the dialog window
+  Centre();
+  UpdateMainPage();
+  return true;
+}
+
+wxPanel *SimpleTextSymbolizerDialog::CreateMainPage(wxWindow * parent)
+{
+//
+// creating the MAIN page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_MAIN);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+// first row: the TextSymbolizer Name
+  wxBoxSizer *nameSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(nameSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *nameLabel = new wxStaticText(panel, wxID_STATIC, wxT("&Name:"));
+  nameSizer->Add(nameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *nameCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_NAME, wxT(""),
+                                        wxDefaultPosition, wxSize(600, 22));
+  nameSizer->Add(nameCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: the TextSymbolizer Title
+  wxBoxSizer *titleSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(titleSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *titleLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Title:"));
+  titleSizer->Add(titleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *titleCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_TITLE, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  titleSizer->Add(titleCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// third row: the TextSymbolizer Abstract
+  wxBoxSizer *absSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(absSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *absLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Abstract:"));
+  absSizer->Add(absLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *abstractCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_ABSTRACT, wxT(""),
+                   wxDefaultPosition, wxSize(600, 60),
+                   wxTE_MULTILINE);
+  absSizer->Add(abstractCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// fourth row: UOM and Visibility Range
+  boxSizer->AddSpacer(50);
+  wxBoxSizer *miscSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(miscSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// fourth row A: Unit Of Measure - UOM
+  wxString uom[3];
+  uom[0] = wxT("&Pixel");
+  uom[1] = wxT("&Metre");
+  uom[2] = wxT("&Inch");
+  wxRadioBox *uomBox = new wxRadioBox(panel, ID_SYMBOLIZER_UOM,
+                                      wxT("&Unit Of Measure"),
+                                      wxDefaultPosition,
+                                      wxDefaultSize, 3,
+                                      uom, 1,
+                                      wxRA_SPECIFY_ROWS);
+  miscSizer->Add(uomBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  uomBox->SetSelection(0);
+// fourth row B: optional Visibility Range
+  miscSizer->AddSpacer(50);
+  wxBoxSizer *visibilityBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  miscSizer->Add(visibilityBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *visibilityBox = new wxStaticBox(panel, wxID_STATIC,
+                                               wxT("Visibility Range"),
+                                               wxDefaultPosition,
+                                               wxDefaultSize);
+  wxBoxSizer *visibilitySizer =
+    new wxStaticBoxSizer(visibilityBox, wxHORIZONTAL);
+  visibilityBoxSizer->Add(visibilitySizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL,
+                          5);
+  wxString range[4];
+  range[0] = wxT("&None");
+  range[1] = wxT("&Min");
+  range[2] = wxT("&Max");
+  range[3] = wxT("&Both");
+  wxRadioBox *rangeBox = new wxRadioBox(panel, ID_SYMBOLIZER_MINMAX_SCALE,
+                                        wxT("&Range Type"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 4,
+                                        range, 2,
+                                        wxRA_SPECIFY_COLS);
+  visibilitySizer->Add(rangeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  rangeBox->SetSelection(0);
+  visibilitySizer->AddSpacer(20);
+  wxBoxSizer *scaleBoxSizer = new wxBoxSizer(wxVERTICAL);
+  visibilitySizer->Add(scaleBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxBoxSizer *scaleMinSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMinSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *minScaleLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Min Scale:"));
+  scaleMinSizer->Add(minScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *minScaleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_MIN_SCALE, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  minScaleCtrl->Enable(false);
+  scaleMinSizer->Add(minScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *scaleMaxSizer = new wxBoxSizer(wxHORIZONTAL);
+  scaleBoxSizer->Add(scaleMaxSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *maxScaleLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Max Scale:"));
+  scaleMaxSizer->Add(maxScaleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *maxScaleCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_MAX_SCALE, wxT("+Infinite"),
+                   wxDefaultPosition, wxSize(100, 22));
+  maxScaleCtrl->Enable(false);
+  scaleMaxSizer->Add(maxScaleCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// fifth row: the Label
+  boxSizer->AddSpacer(30);
+  wxBoxSizer *labelSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(labelSizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxStaticText *labelLabel =
+    new wxStaticText(panel, wxID_STATIC, wxT("&Label:"));
+  labelSizer->Add(labelLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *labelCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_LABEL, wxT(""),
+                                         wxDefaultPosition, wxSize(600, 22));
+  labelSizer->Add(labelCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_UOM, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdUomChanged);
+  Connect(ID_SYMBOLIZER_MINMAX_SCALE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdScaleChanged);
+  return panel;
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdUomChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// UOM selection changed
+//
+  wxRadioBox *uomCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_UOM);
+  switch (uomCtrl->GetSelection())
+    {
+      case 1:
+        Uom = GUI_UOM_METRE;
+        break;
+      case 2:
+        Uom = GUI_UOM_INCH;
+        break;
+      default:
+        Uom = GUI_UOM_PIXEL;
+        break;
+    };
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdScaleChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Visibility Range selection changed
+//
+  wxRadioBox *scaleModeCtrl =
+    (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  switch (scaleModeCtrl->GetSelection())
+    {
+      case 0:
+        MinScale = false;
+        MaxScale = false;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 1:
+        MinScale = true;
+        MaxScale = false;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT("+Infinite"));
+        maxCtrl->Enable(false);
+        break;
+      case 2:
+        MinScale = false;
+        MaxScale = true;
+        minCtrl->SetValue(wxT("0.0"));
+        minCtrl->Enable(false);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+      case 3:
+        MinScale = true;
+        MaxScale = true;
+        minCtrl->SetValue(wxT(""));
+        minCtrl->Enable(true);
+        maxCtrl->SetValue(wxT(""));
+        maxCtrl->Enable(true);
+        break;
+    };
+}
+
+wxPanel *SimpleTextSymbolizerDialog::CreateFontPage(wxWindow * parent)
+{
+//
+// creating the Font page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_FONT);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+
+// GRID to select a Text Font
+  wxBoxSizer *graphicSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(graphicSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *gridBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  graphicSizer->Add(gridBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxStaticBox *gridBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("Registered Text Fonts"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *GridSizer = new wxStaticBoxSizer(gridBox, wxHORIZONTAL);
+  gridBoxSizer->Add(GridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *gridSizer = new wxBoxSizer(wxHORIZONTAL);
+  GridSizer->Add(gridSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  GridCtrl =
+    new wxGrid(panel, ID_SYMBOLIZER_FONT, wxDefaultPosition,
+               wxSize(500, 250), wxALWAYS_SHOW_SB);
+  int count = 0;
+  TextFont *pF = List->GetFirst();
+  while (pF)
+    {
+      // counting how many lines are there
+      count++;
+      pF = pF->GetNext();
+    }
+  GridCtrl->CreateGrid(count, 4, wxGrid::wxGridSelectRows);
+  GridCtrl->SetColLabelValue(0, wxT("FaceName"));
+  GridCtrl->SetColLabelValue(1, wxT("Bold"));
+  GridCtrl->SetColLabelValue(2, wxT("Italic"));
+  GridCtrl->SetColLabelValue(3, wxT("Sample"));
+  count = 0;
+  pF = List->GetFirst();
+  while (pF)
+    {
+      // feeding grid rows
+      GridCtrl->SetCellValue(count, 0, pF->GetFacename());
+      MyFontCellRenderer *renderer = new MyFontCellRenderer;
+      if (pF->IsBold() == true)
+        GridCtrl->SetCellValue(count, 1, wxT("YES"));
+      if (pF->IsItalic() == true)
+        GridCtrl->SetCellValue(count, 2, wxT("YES"));
+      renderer->SetFontExample(pF->GetFontExample());
+      GridCtrl->SetCellRenderer(count, 3, renderer);
+      GridCtrl->SetCellBackgroundColour(count, 3, wxColour(255, 255, 255));
+      count++;
+      pF = pF->GetNext();
+    }
+  GridCtrl->SetRowLabelSize(wxGRID_AUTOSIZE);
+  GridCtrl->AutoSize();
+  GridCtrl->EnableEditing(false);
+  gridSizer->Add(GridCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// second row: Halo 
+  wxBoxSizer *haloBoxSizer = new wxBoxSizer(wxVERTICAL);
+  GridSizer->Add(haloBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxStaticBox *haloBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("Halo"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *haloSizer = new wxStaticBoxSizer(haloBox, wxVERTICAL);
+  haloBoxSizer->Add(haloSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *halo0Sizer = new wxBoxSizer(wxHORIZONTAL);
+  haloSizer->Add(halo0Sizer, 0, wxALIGN_LEFT | wxALL, 0);
+  wxCheckBox *enableHaloCtrl = new wxCheckBox(panel, ID_SYMBOLIZER_HALO_ENABLE,
+                                              wxT("Enable"),
+                                              wxDefaultPosition, wxDefaultSize);
+  enableHaloCtrl->SetValue(false);
+  halo0Sizer->Add(enableHaloCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// Halo Radius
+  wxStaticBox *radiusBox = new wxStaticBox(panel, wxID_STATIC,
+                                           wxT("Radius"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize);
+  wxBoxSizer *radiusSizer = new wxStaticBoxSizer(radiusBox, wxVERTICAL);
+  halo0Sizer->Add(radiusSizer, 0, wxALIGN_RIGHT | wxALL, 2);
+  wxTextCtrl *radiusCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_HALO_RADIUS, wxT("1.0"),
+                   wxDefaultPosition, wxSize(50, 22));
+  radiusCtrl->Enable(false);
+  radiusSizer->Add(radiusCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+// Halo Opacity
+  wxStaticBox *opacityHaloBox = new wxStaticBox(panel, wxID_STATIC,
+                                                wxT("Opacity"),
+                                                wxDefaultPosition,
+                                                wxDefaultSize);
+  wxBoxSizer *opacityHaloSizer =
+    new wxStaticBoxSizer(opacityHaloBox, wxVERTICAL);
+  haloSizer->Add(opacityHaloSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2);
+  wxSlider *opacityHaloCtrl =
+    new wxSlider(panel, ID_SYMBOLIZER_HALO_OPACITY, 100, 0, 100,
+                 wxDefaultPosition, wxSize(130, 45),
+                 wxSL_HORIZONTAL | wxSL_LABELS);
+  opacityHaloSizer->Add(opacityHaloCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  opacityHaloCtrl->Enable(false);
+// Halo color
+  wxStaticBox *haloColorBox = new wxStaticBox(panel, wxID_STATIC,
+                                              wxT("Color"),
+                                              wxDefaultPosition,
+                                              wxDefaultSize);
+  wxBoxSizer *haloColorSizer = new wxStaticBoxSizer(haloColorBox, wxVERTICAL);
+  haloSizer->Add(haloColorSizer, 0, wxALIGN_RIGHT | wxALL, 2);
+  wxBoxSizer *halo2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  haloColorSizer->Add(halo2Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *haloCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_HALO_COLOR,
+                                        HaloColor,
+                                        wxDefaultPosition, wxSize(80, 22));
+  halo2Sizer->Add(haloCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+  haloCtrl->Enable(false);
+  wxTextCtrl *sampleHaloCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_HALO_PICKER_HEX,
+                   wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  wxColour back = wxColour(255, 255, 255);
+  sampleHaloCtrl->SetBackgroundColour(back);
+  halo2Sizer->Add(sampleHaloCtrl, 0, wxALIGN_RIGHT | wxALL, 2);
+  wxButton *pickHalo = new wxButton(panel, ID_SYMBOLIZER_HALO_PICKER_BTN,
+                                    wxT("&Pick a color"));
+  haloColorSizer->Add(pickHalo, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  pickHalo->Enable(false);
+// third row: Size and Fill 
+  wxBoxSizer *fontSizer = new wxBoxSizer(wxHORIZONTAL);
+  boxSizer->Add(fontSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxBoxSizer *font0Sizer = new wxBoxSizer(wxHORIZONTAL);
+  fontSizer->Add(font0Sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// Font Size
+  wxStaticBox *sizeBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("Size"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *sizeSizer = new wxStaticBoxSizer(sizeBox, wxVERTICAL);
+  font0Sizer->Add(sizeSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *sizeCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_SIZE, wxT("10.0"),
+                                        wxDefaultPosition, wxSize(100, 22));
+  sizeSizer->Add(sizeCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// Font Opacity
+  wxStaticBox *opacityFontBox = new wxStaticBox(panel, wxID_STATIC,
+                                                wxT("Opacity"),
+                                                wxDefaultPosition,
+                                                wxDefaultSize);
+  wxBoxSizer *opacityFontSizer =
+    new wxStaticBoxSizer(opacityFontBox, wxVERTICAL);
+  fontSizer->Add(opacityFontSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+  wxSlider *opacityFontCtrl =
+    new wxSlider(panel, ID_SYMBOLIZER_FONT_OPACITY, 100, 0, 100,
+                 wxDefaultPosition, wxSize(250, 45),
+                 wxSL_HORIZONTAL | wxSL_LABELS);
+  opacityFontSizer->Add(opacityFontCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// Font color
+  wxStaticBox *fontColorBox = new wxStaticBox(panel, wxID_STATIC,
+                                              wxT("Color"),
+                                              wxDefaultPosition,
+                                              wxDefaultSize);
+  wxBoxSizer *fontColorSizer = new wxStaticBoxSizer(fontColorBox, wxHORIZONTAL);
+  fontSizer->Add(fontColorSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *font2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  fontColorSizer->Add(font2Sizer, 0, wxALIGN_RIGHT | wxALL, 0);
+  wxTextCtrl *fontCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_FILL_COLOR,
+                                        FillColor,
+                                        wxDefaultPosition, wxSize(80, 22));
+  font2Sizer->Add(fontCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *sampleFontCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_FILL_PICKER_HEX,
+                   wxT("          "),
+                   wxDefaultPosition, wxSize(33, 22), wxTE_READONLY);
+  back = wxColour(0, 0, 0);
+  sampleFontCtrl->SetBackgroundColour(back);
+  font2Sizer->Add(sampleFontCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxButton *pickFont = new wxButton(panel, ID_SYMBOLIZER_FILL_PICKER_BTN,
+                                    wxT("&Pick a color"));
+  fontColorSizer->Add(pickFont, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_FILL_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdColorFillPicker);
+  Connect(ID_SYMBOLIZER_FILL_COLOR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdColorFillChanged);
+  Connect(ID_SYMBOLIZER_HALO_PICKER_BTN, wxEVT_COMMAND_BUTTON_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdColorHaloPicker);
+  Connect(ID_SYMBOLIZER_HALO_ENABLE,
+          wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdHaloEnableChanged);
+  Connect(ID_SYMBOLIZER_HALO_COLOR, wxEVT_COMMAND_TEXT_UPDATED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdColorHaloChanged);
+  return panel;
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdColorFillPicker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_COLOR);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdColorHaloPicker(wxCommandEvent & WXUNUSED(event))
+{
+//
+// color picker
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_HALO_COLOR);
+  wxColour clr = wxNullColour;
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, clr);
+  wxColour color = wxGetColourFromUser(this, clr);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorCtrl->SetValue(str);
+    }
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdHaloEnableChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Graphic Halo enable/disable 
+//
+  wxCheckBox *enableCtrl = (wxCheckBox *) FindWindow(ID_SYMBOLIZER_HALO_ENABLE);
+  if (enableCtrl->IsChecked() == true)
+    HasHalo = true;
+  else
+    HasHalo = false;
+  RetrieveFontPage(false);
+  UpdateFontPage();
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdColorFillChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Fill Color changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_PICKER_HEX);
+  wxColour back = wxColour(0, 0, 0);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdColorHaloChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Halo Color changed: updating the visual sample
+//
+  wxTextCtrl *colorCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_HALO_COLOR);
+  wxTextCtrl *sampleCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_HALO_PICKER_HEX);
+  wxColour back = wxColour(255, 255, 255);
+  wxString str = colorCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(str) == true)
+    ColorMapEntry::GetWxColor(str, back);
+  sampleCtrl->SetBackgroundColour(back);
+  sampleCtrl->Refresh();
+  sampleCtrl->Update();
+}
+
+wxPanel *SimpleTextSymbolizerDialog::CreatePlacementPage(wxWindow * parent)
+{
+//
+// creating the Placement page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_PLACEMENT);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxHORIZONTAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+  wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(mainSizer, 0, wxALIGN_CENTER | wxALL, 0);
+  wxBoxSizer *auxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(auxSizer, 0, wxALIGN_CENTER | wxALL, 0);
+// block 0: Placement Type
+  wxBoxSizer *typeSizer = new wxBoxSizer(wxHORIZONTAL);
+  mainSizer->Add(typeSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxString type[2];
+  type[0] = wxT("&Point");
+  type[1] = wxT("&Line");
+  wxRadioBox *typeBox = new wxRadioBox(panel, ID_SYMBOLIZER_TYPE,
+                                       wxT("&Placement"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 2,
+                                       type, 1,
+                                       wxRA_SPECIFY_ROWS);
+  typeSizer->Add(typeBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  typeBox->SetSelection(0);
+// first row: PointPlacement
+  wxBoxSizer *pointBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  auxSizer->Add(pointBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *pointBox = new wxStaticBox(panel, wxID_STATIC,
+                                          wxT("Point Placement"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *pointSizer = new wxStaticBoxSizer(pointBox, wxHORIZONTAL);
+  pointBoxSizer->Add(pointSizer, 0, wxALIGN_LEFT | wxALL, 5);
+// first row A: Anchor Point
+  wxStaticBox *anchorBox = new wxStaticBox(panel, wxID_STATIC,
+                                           wxT("Anchor Point"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize);
+  wxBoxSizer *anchorSizer = new wxStaticBoxSizer(anchorBox, wxVERTICAL);
+  pointSizer->Add(anchorSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 20);
+  wxBoxSizer *anchor1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  anchorSizer->Add(anchor1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *anchor1Label = new wxStaticText(panel, wxID_STATIC, wxT("X"));
+  anchor1Sizer->Add(anchor1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *anchorXCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_ANCHOR_X, wxT("0.5"),
+                   wxDefaultPosition, wxSize(100, 22));
+  anchor1Sizer->Add(anchorXCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *anchor2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  anchorSizer->Add(anchor2Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *anchor2Label = new wxStaticText(panel, wxID_STATIC, wxT("Y"));
+  anchor2Sizer->Add(anchor2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *anchorYCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_ANCHOR_Y, wxT("0.5"),
+                   wxDefaultPosition, wxSize(100, 22));
+  anchor2Sizer->Add(anchorYCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// first row B: Displacement
+  wxStaticBox *displacementBox = new wxStaticBox(panel, wxID_STATIC,
+                                                 wxT("Displacement"),
+                                                 wxDefaultPosition,
+                                                 wxDefaultSize);
+  wxBoxSizer *displacementSizer =
+    new wxStaticBoxSizer(displacementBox, wxVERTICAL);
+  pointSizer->Add(displacementSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 20);
+  wxBoxSizer *displ1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  displacementSizer->Add(displ1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *displ1Label = new wxStaticText(panel, wxID_STATIC, wxT("X"));
+  displ1Sizer->Add(displ1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *displacementXCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_DISPLACEMENT_X, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  displ1Sizer->Add(displacementXCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxBoxSizer *displ2Sizer = new wxBoxSizer(wxHORIZONTAL);
+  displacementSizer->Add(displ2Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticText *displ2Label = new wxStaticText(panel, wxID_STATIC, wxT("Y"));
+  displ2Sizer->Add(displ2Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *displacementYCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_DISPLACEMENT_Y, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  displ2Sizer->Add(displacementYCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// first row C: Rotation
+  wxStaticBox *rotBox = new wxStaticBox(panel, wxID_STATIC,
+                                        wxT("Rotation"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize);
+  wxBoxSizer *rotSizer = new wxStaticBoxSizer(rotBox, wxVERTICAL);
+  pointSizer->Add(rotSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 20);
+  wxBoxSizer *rot1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  rotSizer->Add(rot1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxTextCtrl *rotCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_ROTATION, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  rot1Sizer->Add(rotCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// second row: LinePlacement
+  wxBoxSizer *lineBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  auxSizer->Add(lineBoxSizer, 0, wxALIGN_LEFT | wxALL, 0);
+  wxStaticBox *lineBox = new wxStaticBox(panel, wxID_STATIC,
+                                         wxT("Line Placement"),
+                                         wxDefaultPosition,
+                                         wxDefaultSize);
+  wxBoxSizer *lineSizer = new wxStaticBoxSizer(lineBox, wxVERTICAL);
+  lineBoxSizer->Add(lineSizer, 0, wxALIGN_LEFT | wxALL, 5);
+// second row A: PerpendicularOffset
+  wxBoxSizer *perpendicularBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  lineSizer->Add(perpendicularBoxSizer, 0,
+                 wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxStaticBox *perpendicularBox = new wxStaticBox(panel, wxID_STATIC,
+                                                  wxT("Perpendicular Offset"),
+                                                  wxDefaultPosition,
+                                                  wxDefaultSize);
+  wxBoxSizer *perpendicularSizer =
+    new wxStaticBoxSizer(perpendicularBox, wxVERTICAL);
+  perpendicularBoxSizer->Add(perpendicularSizer, 0,
+                             wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxBoxSizer *perp1Sizer = new wxBoxSizer(wxHORIZONTAL);
+  perpendicularSizer->Add(perp1Sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxTextCtrl *perpendicularCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_PERPENDICULAR, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  perp1Sizer->Add(perpendicularCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  perpendicularCtrl->Enable(false);
+  wxStaticText *perp1Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT
+                                              ("Draw lines in parallel to the original geometry."));
+  perp1Sizer->Add(perp1Label, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2);
+  wxStaticText *perp2Label = new wxStaticText(panel, wxID_STATIC,
+                                              wxT
+                                              ("Positive to the left-hand side. Negative numbers mean right."));
+  perpendicularSizer->Add(perp2Label, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+// second row B: IsRepeated, InitialGap and Gap
+  wxBoxSizer *repeatedBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  lineSizer->Add(repeatedBoxSizer, 0, wxALIGN_LEFT | wxALL, 0);
+  wxStaticBox *repeatedBox = new wxStaticBox(panel, wxID_STATIC,
+                                             wxT("Repeated Label"),
+                                             wxDefaultPosition,
+                                             wxDefaultSize);
+  wxBoxSizer *repeatedSizer = new wxStaticBoxSizer(repeatedBox, wxHORIZONTAL);
+  repeatedBoxSizer->Add(repeatedSizer, 0, wxALIGN_LEFT | wxALL, 5);
+  wxCheckBox *isRepeatedCtrl = new wxCheckBox(panel, ID_SYMBOLIZER_IS_REPEATED,
+                                              wxT("is Repeated"),
+                                              wxDefaultPosition, wxDefaultSize);
+  isRepeatedCtrl->SetValue(false);
+  isRepeatedCtrl->Enable(false);
+  repeatedSizer->Add(isRepeatedCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxStaticBox *inigapBox = new wxStaticBox(panel, wxID_STATIC,
+                                           wxT("Initial Gap"),
+                                           wxDefaultPosition,
+                                           wxDefaultSize);
+  wxBoxSizer *inigapSizer = new wxStaticBoxSizer(inigapBox, wxVERTICAL);
+  repeatedSizer->Add(inigapSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxTextCtrl *inigapCtrl =
+    new wxTextCtrl(panel, ID_SYMBOLIZER_INITIAL_GAP, wxT("0.0"),
+                   wxDefaultPosition, wxSize(100, 22));
+  inigapCtrl->Enable(false);
+  inigapSizer->Add(inigapCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxStaticBox *gapBox = new wxStaticBox(panel, wxID_STATIC,
+                                        wxT("Gap"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize);
+  wxBoxSizer *gapSizer = new wxStaticBoxSizer(gapBox, wxVERTICAL);
+  repeatedSizer->Add(gapSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+  wxTextCtrl *gapCtrl = new wxTextCtrl(panel, ID_SYMBOLIZER_GAP, wxT("0.0"),
+                                       wxDefaultPosition, wxSize(100, 22));
+  gapCtrl->Enable(false);
+  gapSizer->Add(gapCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+// second row C: IsAligned and Generalize
+  wxBoxSizer *optBoxSizer = new wxBoxSizer(wxHORIZONTAL);
+  repeatedBoxSizer->Add(optBoxSizer, 0, wxALIGN_LEFT | wxALL, 0);
+  wxStaticBox *optBox = new wxStaticBox(panel, wxID_STATIC,
+                                        wxT("Options"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize);
+  wxBoxSizer *optSizer = new wxStaticBoxSizer(optBox, wxVERTICAL);
+  optBoxSizer->Add(optSizer, 0, wxALIGN_LEFT | wxALL, 5);
+  wxCheckBox *isAlignedCtrl = new wxCheckBox(panel, ID_SYMBOLIZER_IS_ALIGNED,
+                                             wxT("is Aligned"),
+                                             wxDefaultPosition, wxDefaultSize);
+  isAlignedCtrl->SetValue(false);
+  isAlignedCtrl->Enable(false);
+  optSizer->Add(isAlignedCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxCheckBox *generalizeCtrl = new wxCheckBox(panel, ID_SYMBOLIZER_GENERALIZE,
+                                              wxT("Generalize Line"),
+                                              wxDefaultPosition, wxDefaultSize);
+  generalizeCtrl->SetValue(false);
+  generalizeCtrl->Enable(false);
+  optSizer->Add(generalizeCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+
+
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_TYPE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdTypeChanged);
+  Connect(ID_SYMBOLIZER_IS_REPEATED,
+          wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdIsRepeatedChanged);
+  Connect(ID_SYMBOLIZER_IS_ALIGNED,
+          wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdIsAlignedChanged);
+  Connect(ID_SYMBOLIZER_GENERALIZE,
+          wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdGeneralizeLineChanged);
+  return panel;
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdTypeChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Symbol Type selection changed
+//
+  wxRadioBox *typeCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_TYPE);
+  switch (typeCtrl->GetSelection())
+    {
+      case 1:
+        PointPlacement = false;
+        break;
+      default:
+        PointPlacement = true;
+        break;
+    };
+  RetrievePlacementPage(false);
+  UpdatePlacementPage();
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdIsRepeatedChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Label IsRepeated enable/disable 
+//
+  wxCheckBox *repeatedCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_IS_REPEATED);
+  if (repeatedCtrl->IsChecked() == true)
+    IsRepeated = true;
+  else
+    IsRepeated = false;
+  RetrievePlacementPage(false);
+  UpdatePlacementPage();
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdIsAlignedChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Label IsAligned enable/disable 
+//
+  wxCheckBox *alignedCtrl = (wxCheckBox *) FindWindow(ID_SYMBOLIZER_IS_ALIGNED);
+  if (alignedCtrl->IsChecked() == true)
+    IsAligned = true;
+  else
+    IsAligned = false;
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdGeneralizeLineChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Label GeneralizeLine enable/disable 
+//
+  wxCheckBox *generalizeCtrl =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_GENERALIZE);
+  if (generalizeCtrl->IsChecked() == true)
+    GeneralizeLine = true;
+  else
+    GeneralizeLine = false;
+}
+
+wxPanel *SimpleTextSymbolizerDialog::CreatePreviewPage(wxWindow * parent)
+{
+//
+// creating the Preview page
+//
+  wxPanel *panel = new wxPanel(parent, ID_PANE_PREVIEW);
+  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+  panel->SetSizer(topSizer);
+  wxBoxSizer *boxSizer = new wxBoxSizer(wxHORIZONTAL);
+  topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
+  wxBoxSizer *previewBoxSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(previewBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
+// creating a control to show the TextSymbolizer Preview
+  wxStaticBox *previewBox = new wxStaticBox(panel, wxID_STATIC,
+                                            wxT("TextSymbolizer Preview"),
+                                            wxDefaultPosition,
+                                            wxDefaultSize);
+  wxBoxSizer *previewSizer = new wxStaticBoxSizer(previewBox, wxVERTICAL);
+  previewBoxSizer->Add(previewSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  DrawPreview(500, 300);
+  SymbolizerPreview *previewCtrl =
+    new SymbolizerPreview(this, panel, ID_SYMBOLIZER_PREVIEW,
+                          PreviewBackBitmap, wxSize(500, 300));
+  previewSizer->Add(previewCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
+// Background selector
+  wxBoxSizer *extraSizer = new wxBoxSizer(wxVERTICAL);
+  boxSizer->Add(extraSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxString back[3];
+  back[0] = wxT("&Checked");
+  back[1] = wxT("&White");
+  back[2] = wxT("&Black");
+  wxRadioBox *backBox = new wxRadioBox(panel, ID_SYMBOLIZER_BACKGROUND,
+                                       wxT("&Background"),
+                                       wxDefaultPosition,
+                                       wxDefaultSize, 3,
+                                       back, 1,
+                                       wxRA_SPECIFY_COLS);
+  extraSizer->Add(backBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  backBox->SetSelection(0);
+// Crosshair selector
+  wxString crosshair[2];
+  crosshair[0] = wxT("&Show");
+  crosshair[1] = wxT("&Hide");
+  wxRadioBox *crossBox = new wxRadioBox(panel, ID_SYMBOLIZER_CROSSHAIR,
+                                        wxT("&Crosshair"),
+                                        wxDefaultPosition,
+                                        wxDefaultSize, 2,
+                                        crosshair, 1,
+                                        wxRA_SPECIFY_COLS);
+  extraSizer->Add(crossBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  crossBox->SetSelection(0);
+// Reference Line selector
+  wxString refline[2];
+  refline[0] = wxT("&Show");
+  refline[1] = wxT("&Hide");
+  wxRadioBox *reflineBox = new wxRadioBox(panel, ID_SYMBOLIZER_REFLINE,
+                                          wxT("&Test Line"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize, 2,
+                                          refline, 1,
+                                          wxRA_SPECIFY_COLS);
+  extraSizer->Add(reflineBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  reflineBox->SetSelection(0);
+  panel->SetSizer(topSizer);
+  topSizer->Fit(panel);
+// appends event handlers
+  Connect(ID_SYMBOLIZER_BACKGROUND, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdBackgroundChanged);
+  Connect(ID_SYMBOLIZER_CROSSHAIR, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdCrosshairChanged);
+  Connect(ID_SYMBOLIZER_REFLINE, wxEVT_COMMAND_RADIOBOX_SELECTED,
+          (wxObjectEventFunction) &
+          SimpleTextSymbolizerDialog::OnCmdReferenceLineChanged);
+  return panel;
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdBackgroundChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Preview Background selection changed
+//
+  wxRadioBox *backCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_BACKGROUND);
+  switch (backCtrl->GetSelection())
+    {
+      case 1:
+        PreviewBackground = GUI_PREVIEW_BACKGROUND_WHITE;
+        break;
+      case 2:
+        PreviewBackground = GUI_PREVIEW_BACKGROUND_BLACK;
+        break;
+      default:
+        PreviewBackground = GUI_PREVIEW_BACKGROUND_CHECKED;
+        break;
+    };
+  UpdatePreviewPage();
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdCrosshairChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Preview Background selection changed
+//
+  wxRadioBox *crossCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_CROSSHAIR);
+  switch (crossCtrl->GetSelection())
+    {
+      case 1:
+        Crosshair = false;
+        break;
+      default:
+        Crosshair = true;
+        break;
+    };
+  UpdatePreviewPage();
+}
+
+void SimpleTextSymbolizerDialog::
+OnCmdReferenceLineChanged(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Test Line selection changed
+//
+  wxRadioBox *reflineCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_REFLINE);
+  switch (reflineCtrl->GetSelection())
+    {
+      case 1:
+        ReferenceLine = false;
+        break;
+      default:
+        ReferenceLine = true;
+        break;
+    };
+  UpdatePreviewPage();
+}
+
+void SimpleTextSymbolizerDialog::DrawPreview(int horz, int vert)
+{
+//
+// drawing a Symbolizer Preview
+//
+  PreviewBackBitmap.Create(horz, vert);
+  wxMemoryDC dc(PreviewBackBitmap);
+//
+// background filling
+//
+  wxImage img(24, 24);
+  for (int y = 0; y < 24; y++)
+    {
+      // creating a checked background
+      for (int x = 0; x < 24; x++)
+        {
+          if (y < 12)
+            {
+              if (x < 12)
+                img.SetRGB(x, y, 176, 176, 176);
+              else
+                img.SetRGB(x, y, 208, 208, 208);
+          } else
+            {
+              if (x < 12)
+                img.SetRGB(x, y, 208, 208, 208);
+              else
+                img.SetRGB(x, y, 176, 176, 176);
+            }
+        }
+    }
+  wxBrush stipple(img);
+  dc.SetBrush(stipple);
+  dc.DrawRectangle(0, 0, horz, vert);
+}
+
+void SimpleTextSymbolizerDialog::CreateButtons()
+{
+// 
+// adding the common Buttons
+//
+  wxBoxSizer *topSizer = (wxBoxSizer *) (this->GetSizer());
+  wxBoxSizer *btnBox = new wxBoxSizer(wxHORIZONTAL);
+  topSizer->Add(btnBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
+  wxButton *insert =
+    new wxButton(this, ID_SYMBOLIZER_INSERT, wxT("&Insert into DBMS"));
+  btnBox->Add(insert, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *exp =
+    new wxButton(this, ID_SYMBOLIZER_EXPORT, wxT("&Export to file"));
+  btnBox->Add(exp, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxButton *copy = new wxButton(this, ID_SYMBOLIZER_COPY, wxT("&Copy"));
+  btnBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  btnBox->AddSpacer(100);
+  wxButton *ok = new wxButton(this, wxID_OK, wxT("&Quit"));
+  btnBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+}
+
+bool SimpleTextSymbolizerDialog::FinalValidityCheck()
+{
+//
+// last check before generating the SLD/SE Style
+//
+  if (Name.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the TextSymbolizer NAME !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  if (Label.Len() < 1)
+    {
+      wxMessageBox(wxT("You must specify the TextSymbolizer LABEL !!!"),
+                   wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+      return false;
+    }
+  if (Title.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some TextSymbolizer TITLE is warmly suggested\n\n");
+      msg += wxT("Do you really confirm leaving an empty (undefined) Title ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  if (Abstract.Len() < 1)
+    {
+      wxString msg =
+        wxT("Setting some TextSymbolizer ABSTRACT is warmly suggested\n\n");
+      msg +=
+        wxT("Do you really confirm leaving an empty (undefined) Abstract ?");
+      if (wxMessageBox
+          (msg, wxT("spatialite_gui"), wxYES_NO | wxICON_WARNING,
+           this) != wxYES)
+        return false;
+    }
+  return true;
+}
+
+bool SimpleTextSymbolizerDialog::RetrieveMainPage()
+{
+//
+// retrieving params from the MAIN page
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  Name = nameCtrl->GetValue();
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  Title = titleCtrl->GetValue();
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  Abstract = absCtrl->GetValue();
+  wxTextCtrl *labelCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_LABEL);
+  Label = labelCtrl->GetValue();
+  if (MinScale == true)
+    {
+      wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+      wxString value = minCtrl->GetValue();
+      if (value.ToDouble(&MinScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MinScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MIN_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MaxScale == true)
+    {
+      wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+      wxString value = maxCtrl->GetValue();
+      if (value.ToDouble(&MaxScaleDenominator) != true)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+      if (MaxScaleDenominator < 0.0)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE must be a positive number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (MinScale == true && MaxScale == true)
+    {
+      if (MinScaleDenominator >= MaxScaleDenominator)
+        {
+          wxMessageBox(wxT
+                       ("MAX_SCALE is always expected to be greater than MIN_SCALE !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  return true;
+}
+
+void SimpleTextSymbolizerDialog::UpdateMainPage()
+{
+//
+// updating the MAIN page
+//
+  wxTextCtrl *nameCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_NAME);
+  nameCtrl->SetValue(Name);
+  wxTextCtrl *titleCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_TITLE);
+  titleCtrl->SetValue(Title);
+  wxTextCtrl *absCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ABSTRACT);
+  absCtrl->SetValue(Abstract);
+  wxTextCtrl *labelCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_LABEL);
+  labelCtrl->SetValue(Label);
+  wxRadioBox *uomBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_UOM);
+  switch (Uom)
+    {
+      case GUI_UOM_METRE:
+        uomBox->SetSelection(1);
+        break;
+      case GUI_UOM_INCH:
+        uomBox->SetSelection(2);
+        break;
+      default:
+        uomBox->SetSelection(0);
+        break;
+    };
+  wxRadioBox *rangeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_MINMAX_SCALE);
+  if (MinScale != true && MaxScale != true)
+    rangeBox->SetSelection(0);
+  else if (MinScale == true && MaxScale != true)
+    rangeBox->SetSelection(1);
+  else if (MinScale != true && MaxScale == true)
+    rangeBox->SetSelection(2);
+  else
+    rangeBox->SetSelection(3);
+  wxTextCtrl *minCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MIN_SCALE);
+  char dummy[64];
+  wxString str;
+  if (MinScale == true)
+    {
+      sprintf(dummy, "%1.2f", MinScaleDenominator);
+      str = wxString::FromUTF8(dummy);
+      minCtrl->SetValue(str);
+      minCtrl->Enable(true);
+  } else
+    {
+      str = wxT("0.0");
+      minCtrl->SetValue(str);
+      minCtrl->Enable(false);
+    }
+  wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_MAX_SCALE);
+  if (MaxScale == true)
+    {
+      sprintf(dummy, "%1.2f", MaxScaleDenominator);
+      str = wxString::FromUTF8(dummy);
+      maxCtrl->SetValue(str);
+      maxCtrl->Enable(true);
+  } else
+    {
+      str = wxT("+Infinite");
+      maxCtrl->SetValue(str);
+      maxCtrl->Enable(false);
+    }
+}
+
+bool SimpleTextSymbolizerDialog::RetrieveFontPage(bool check)
+{
+//
+// retrieving params from the FONT page
+//
+  int selCount = 0;
+  int selected = -1;
+  for (int i = 0; i < GridCtrl->GetNumberRows(); i++)
+    {
+      if (GridCtrl->IsInSelection(i, 0) == true)
+        {
+          selected = i;
+          selCount++;
+        }
+    }
+  if (selCount < 1)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("You must select some Text Font !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (selCount > 1)
+    {
+      if (check == true)
+        {
+          wxString msg = wxT("You must select just a single TextFont !!!\n");
+          msg += wxT("Multiple selection is not supported");
+          wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  List->FindByIndex(selected, FontFamily, &FontStyle, &FontWeight);
+  wxTextCtrl *sizeCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_SIZE);
+  wxString value = sizeCtrl->GetValue();
+  if (value.ToDouble(&FontSize) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("FONT-SIZE isn't a valid decimal number !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  if (FontSize <= 0.0)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("FONT-SIZE should be a positive numberr !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  wxSlider *opacityFontCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_FONT_OPACITY);
+  FillOpacity = opacityFontCtrl->GetValue() / 100.0;
+  wxTextCtrl *colorFillCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_COLOR);
+  wxString color = colorFillCtrl->GetValue();
+  if (ColorMapEntry::IsValidColor(color) != true)
+    {
+      if (check == true)
+        {
+          wxMessageBox(wxT
+                       ("FILL-COLOR isn't a valid HexRGB color !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return false;
+        }
+    }
+  FillColor = color;
+
+  if (HasHalo == true)
+    {
+      wxSlider *opacityHaloCtrl =
+        (wxSlider *) FindWindow(ID_SYMBOLIZER_HALO_OPACITY);
+      HaloOpacity = opacityHaloCtrl->GetValue() / 100.0;
+      wxTextCtrl *radiusCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_HALO_RADIUS);
+      wxString value = radiusCtrl->GetValue();
+      if (value.ToDouble(&HaloRadius) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("HALO-RADIUS isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (HaloRadius <= 0.0)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("HALO-RADIUS should be a positive number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      wxTextCtrl *colorHaloCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_HALO_COLOR);
+      wxString color = colorHaloCtrl->GetValue();
+      if (ColorMapEntry::IsValidColor(color) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("HALO-COLOR isn't a valid HexRGB color !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      HaloColor = color;
+    }
+  return true;
+}
+
+void SimpleTextSymbolizerDialog::UpdateFontPage()
+{
+//
+// updating the FONT page
+//
+  wxSlider *opacityFontCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_FONT_OPACITY);
+  opacityFontCtrl->SetValue(FillOpacity * 100.0);
+  wxTextCtrl *colorFontCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_COLOR);
+  wxColour color = wxNullColour;
+  ColorMapEntry::GetWxColor(FillColor, color);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorFontCtrl->SetValue(str);
+    }
+  wxTextCtrl *sizeCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_SIZE);
+  char dummy[64];
+  sprintf(dummy, "%1.2f", FontSize);
+  wxString str = wxString::FromUTF8(dummy);
+  sizeCtrl->SetValue(str);
+  wxTextCtrl *sampleFontCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_FILL_PICKER_HEX);
+  wxCheckBox *enableHaloBox =
+    (wxCheckBox *) FindWindow(ID_SYMBOLIZER_HALO_ENABLE);
+  if (HasHalo == true)
+    enableHaloBox->SetValue(true);
+  else
+    enableHaloBox->SetValue(false);
+  wxTextCtrl *radiusCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_HALO_RADIUS);
+  wxTextCtrl *colorHaloCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_HALO_COLOR);
+  wxTextCtrl *sampleHaloCtrl =
+    (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_HALO_PICKER_HEX);
+  wxButton *pickHalo = (wxButton *) FindWindow(ID_SYMBOLIZER_HALO_PICKER_BTN);
+  wxSlider *opacityHaloCtrl =
+    (wxSlider *) FindWindow(ID_SYMBOLIZER_HALO_OPACITY);
+  opacityHaloCtrl->SetValue(HaloOpacity * 100.0);
+  sprintf(dummy, "%1.2f", HaloRadius);
+  str = wxString::FromUTF8(dummy);
+  radiusCtrl->SetValue(str);
+  color = wxNullColour;
+  ColorMapEntry::GetWxColor(HaloColor, color);
+  if (color.IsOk() == true)
+    {
+      char hex[16];
+      sprintf(hex, "#%02x%02x%02x", color.Red(), color.Green(), color.Blue());
+      wxString str = wxString::FromUTF8(hex);
+      colorHaloCtrl->SetValue(str);
+    }
+  if (HasHalo == false)
+    {
+      opacityHaloCtrl->Enable(false);
+      pickHalo->Enable(false);
+      colorHaloCtrl->Enable(false);
+      radiusCtrl->Enable(false);
+  } else
+    {
+      opacityHaloCtrl->Enable(true);
+      pickHalo->Enable(true);
+      colorHaloCtrl->Enable(true);
+      radiusCtrl->Enable(true);
+    }
+}
+
+bool SimpleTextSymbolizerDialog::RetrievePlacementPage(bool check)
+{
+//
+// retrieving params from the Placement page
+//
+  if (PointPlacement == true)
+    {
+      // Point Placement
+      wxTextCtrl *rotationCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ROTATION);
+      wxString value = rotationCtrl->GetValue();
+      if (value.ToDouble(&Rotation) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("ROTATION isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      wxTextCtrl *anchorXCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ANCHOR_X);
+      value = anchorXCtrl->GetValue();
+      if (value.ToDouble(&AnchorPointX) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("ANCHOR-POINT-X isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (AnchorPointX < 0.0 || AnchorPointX > 1.0)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("ANCHOR-POINT-X must be between 0.0 and 1.0 !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      wxTextCtrl *anchorYCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ANCHOR_Y);
+      value = anchorYCtrl->GetValue();
+      if (value.ToDouble(&AnchorPointY) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("ANCHOR-POINT-Y isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (AnchorPointY < 0.0 || AnchorPointY > 1.0)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("ANCHOR-POINT-Y must be between 0.0 and 1.0 !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      wxTextCtrl *displXCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_DISPLACEMENT_X);
+      value = displXCtrl->GetValue();
+      if (value.ToDouble(&DisplacementX) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("DISPLACEMENT-X isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      wxTextCtrl *displYCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_DISPLACEMENT_Y);
+      value = displYCtrl->GetValue();
+      if (value.ToDouble(&DisplacementY) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("DISPLACEMENT-Y isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+  } else
+    {
+      // Line Placement
+      wxTextCtrl *perpCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_PERPENDICULAR);
+      wxString value = perpCtrl->GetValue();
+      if (value.ToDouble(&PerpendicularOffset) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("PERPENDICULAR-OFFSET isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      wxTextCtrl *inigapCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_INITIAL_GAP);
+      value = inigapCtrl->GetValue();
+      if (value.ToDouble(&InitialGap) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("INITIAL-GAP isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (InitialGap < 0.0)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("INITIAL-GAP should be a positive number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      wxTextCtrl *gapCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_GAP);
+      value = gapCtrl->GetValue();
+      if (value.ToDouble(&Gap) != true)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("GAP isn't a valid decimal number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+      if (InitialGap < 0.0)
+        {
+          if (check == true)
+            {
+              wxMessageBox(wxT
+                           ("GAP should be a positive number !!!"),
+                           wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+              return false;
+            }
+        }
+    }
+  return true;
+}
+
+void SimpleTextSymbolizerDialog::UpdatePlacementPage()
+{
+//
+// updating the Placement page
+//
+  wxRadioBox *typeBox = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_TYPE);
+  switch (PointPlacement)
+    {
+      case false:
+        typeBox->SetSelection(1);
+        break;
+      default:
+        typeBox->SetSelection(0);
+        break;
+    };
+  if (PointPlacement == true)
+    {
+      // Point Placement
+      wxTextCtrl *rotationCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ROTATION);
+      char dummy[64];
+      sprintf(dummy, "%1.2f", Rotation);
+      wxString str = wxString::FromUTF8(dummy);
+      rotationCtrl->SetValue(str);
+      rotationCtrl->Enable(true);
+      wxTextCtrl *anchorXCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ANCHOR_X);
+      sprintf(dummy, "%1.2f", AnchorPointX);
+      str = wxString::FromUTF8(dummy);
+      anchorXCtrl->SetValue(str);
+      anchorXCtrl->Enable(true);
+      wxTextCtrl *anchorYCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ANCHOR_Y);
+      sprintf(dummy, "%1.2f", AnchorPointY);
+      str = wxString::FromUTF8(dummy);
+      anchorYCtrl->SetValue(str);
+      anchorYCtrl->Enable(true);
+      wxTextCtrl *displXCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_DISPLACEMENT_X);
+      sprintf(dummy, "%1.2f", DisplacementX);
+      str = wxString::FromUTF8(dummy);
+      displXCtrl->SetValue(str);
+      displXCtrl->Enable(true);
+      wxTextCtrl *displYCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_DISPLACEMENT_Y);
+      sprintf(dummy, "%1.2f", DisplacementY);
+      str = wxString::FromUTF8(dummy);
+      displYCtrl->SetValue(str);
+      displYCtrl->Enable(true);
+      wxTextCtrl *perpCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_PERPENDICULAR);
+      perpCtrl->Enable(false);
+      wxCheckBox *repeatBox =
+        (wxCheckBox *) FindWindow(ID_SYMBOLIZER_IS_REPEATED);
+      repeatBox->Enable(false);
+      wxTextCtrl *inigapCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_INITIAL_GAP);
+      inigapCtrl->Enable(false);
+      wxTextCtrl *gapCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_GAP);
+      gapCtrl->Enable(false);
+      wxCheckBox *alignBox =
+        (wxCheckBox *) FindWindow(ID_SYMBOLIZER_IS_ALIGNED);
+      alignBox->Enable(false);
+      wxCheckBox *generalizeBox =
+        (wxCheckBox *) FindWindow(ID_SYMBOLIZER_GENERALIZE);
+      generalizeBox->Enable(false);
+  } else
+    {
+      // Line Placement
+      wxTextCtrl *perpCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_PERPENDICULAR);
+      char dummy[64];
+      sprintf(dummy, "%1.2f", PerpendicularOffset);
+      wxString str = wxString::FromUTF8(dummy);
+      perpCtrl->SetValue(str);
+      perpCtrl->Enable(true);
+      wxCheckBox *repeatBox =
+        (wxCheckBox *) FindWindow(ID_SYMBOLIZER_IS_REPEATED);
+      if (IsRepeated == true)
+        repeatBox->SetValue(true);
+      else
+        repeatBox->SetValue(false);
+      repeatBox->Enable(true);
+      wxTextCtrl *inigapCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_INITIAL_GAP);
+      sprintf(dummy, "%1.2f", InitialGap);
+      str = wxString::FromUTF8(dummy);
+      inigapCtrl->SetValue(str);
+      wxTextCtrl *gapCtrl = (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_GAP);
+      sprintf(dummy, "%1.2f", Gap);
+      str = wxString::FromUTF8(dummy);
+      gapCtrl->SetValue(str);
+      if (IsRepeated == true)
+        {
+          inigapCtrl->Enable(true);
+          gapCtrl->Enable(true);
+      } else
+        {
+          inigapCtrl->Enable(false);
+          gapCtrl->Enable(false);
+        }
+      wxCheckBox *alignBox =
+        (wxCheckBox *) FindWindow(ID_SYMBOLIZER_IS_ALIGNED);
+      if (IsAligned == true)
+        alignBox->SetValue(true);
+      else
+        alignBox->SetValue(false);
+      alignBox->Enable(true);
+      wxCheckBox *generalizeBox =
+        (wxCheckBox *) FindWindow(ID_SYMBOLIZER_GENERALIZE);
+      if (GeneralizeLine == true)
+        generalizeBox->SetValue(true);
+      else
+        generalizeBox->SetValue(false);
+      generalizeBox->Enable(true);
+      wxTextCtrl *rotationCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ROTATION);
+      rotationCtrl->Enable(false);
+      wxTextCtrl *anchorXCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ANCHOR_X);
+      anchorXCtrl->Enable(false);
+      wxTextCtrl *anchorYCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_ANCHOR_Y);
+      anchorYCtrl->Enable(false);
+      wxTextCtrl *displXCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_DISPLACEMENT_X);
+      displXCtrl->Enable(false);
+      wxTextCtrl *displYCtrl =
+        (wxTextCtrl *) FindWindow(ID_SYMBOLIZER_DISPLACEMENT_Y);
+      displYCtrl->Enable(false);
+    }
+}
+
+bool SimpleTextSymbolizerDialog::RetrievePreviewPage()
+{
+//
+// retrieving params from the PREVIEW page
+//
+  return true;
+}
+
+gaiaGeomCollPtr SimpleTextSymbolizerDialog::PrepareLinestring(double
+                                                              perpendicular_offset)
+{
+// preparing the reference Line
+  double pi = 3.14159265359;
+  gaiaDynamicLinePtr dyn = gaiaAllocDynamicLine();
+  gaiaAppendPointToDynamicLine(dyn, 200.0, 75.0);
+  gaiaAppendPointToDynamicLine(dyn, 150.0, 60.0);
+  gaiaAppendPointToDynamicLine(dyn, 50.0, 60.0);
+  for (double rads = pi; rads > 0.0; rads -= 0.666666)
+    {
+      double x = 150.0 + (100.0 * cos(rads));
+      double y = 150.0 + (100.0 * sin(rads));
+      gaiaAppendPointToDynamicLine(dyn, x, y);
+    }
+  for (double rads = pi; rads <= (pi * 2.0); rads += 0.1)
+    {
+      double x = 350.0 + (100.0 * cos(rads));
+      double y = 150.0 + (100.0 * sin(rads));
+      gaiaAppendPointToDynamicLine(dyn, x, y);
+    }
+  gaiaAppendPointToDynamicLine(dyn, 450.0, 240.0);
+  gaiaAppendPointToDynamicLine(dyn, 350.0, 240.0);
+  gaiaAppendPointToDynamicLine(dyn, 300.0, 225.0);
+
+  int points = 0;
+  gaiaPointPtr pt = dyn->First;
+  while (pt != NULL)
+    {
+      // counting how many Points are there
+      points++;
+      pt = pt->Next;
+    }
+  gaiaGeomCollPtr geom = gaiaAllocGeomColl();
+  gaiaLinestringPtr ln = gaiaAddLinestringToGeomColl(geom, points);
+  int iv = 0;
+  pt = dyn->First;
+  while (pt != NULL)
+    {
+      // preparing the Linestring
+      gaiaSetPoint(ln->Coords, iv, pt->X, pt->Y);
+      iv++;
+      pt = pt->Next;
+    }
+  gaiaFreeDynamicLine(dyn);
+
+  gaiaGeomCollPtr geom2;
+  if (perpendicular_offset != 0.0)
+    {
+      // Offset Curve
+      geom2 =
+        gaiaOffsetCurve_r(MainFrame->GetSpliteInternalCache(), geom,
+                          perpendicular_offset, 16, 0);
+      gaiaFreeGeomColl(geom);
+  } else
+    {
+      // unchanged
+      geom2 = geom;
+    }
+  return geom2;
+}
+
+void SimpleTextSymbolizerDialog::PrepareLinestringPath(void *xctx,
+                                                       double
+                                                       perpendicular_offset)
+{
+// preparing the Line Path
+  gaiaGeomCollPtr geom = PrepareLinestring(perpendicular_offset);
+  if (geom == NULL)
+    return;
+
+  gaiaLinestringPtr ln = geom->FirstLinestring;
+  rl2GraphicsContextPtr ctx = (rl2GraphicsContextPtr) xctx;
+  for (int iv = 0; iv < ln->Points; iv++)
+    {
+      double x;
+      double y;
+      gaiaGetPoint(ln->Coords, iv, &x, &y);
+      if (iv == 0)
+        rl2_graph_move_to_point(ctx, x, y);
+      else
+        rl2_graph_add_line_to_path(ctx, x, y);
+    }
+  gaiaFreeGeomColl(geom);
+}
+
+void SimpleTextSymbolizerDialog::GetLineCenterPoint(double perpendicular_offset,
+                                                    double *x, double *y)
+{
+// computing the Reference Line Centre Point
+  bool ok = 0;
+  unsigned char *blob;
+  int size;
+  sqlite3_stmt *stmt = NULL;
+  int ret;
+  const char *sql = "SELECT ST_Line_Interpolate_Point(?, 0.5)";
+  gaiaGeomCollPtr geom = PrepareLinestring(perpendicular_offset);
+  if (geom == NULL)
+    goto error;
+
+  ret =
+    sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt, NULL);
+  if (ret != SQLITE_OK)
+    goto error;
+  sqlite3_reset(stmt);
+  sqlite3_clear_bindings(stmt);
+  gaiaToSpatiaLiteBlobWkb(geom, &blob, &size);
+  sqlite3_bind_blob(stmt, 1, blob, size, free);
+  while (1)
+    {
+      ret = sqlite3_step(stmt);
+      if (ret == SQLITE_DONE)
+        break;
+      if (ret == SQLITE_ROW)
+        {
+          if (sqlite3_column_type(stmt, 0) == SQLITE_BLOB)
+            {
+              blob = (unsigned char *) sqlite3_column_blob(stmt, 0);
+              size = sqlite3_column_bytes(stmt, 0);
+              gaiaGeomCollPtr g =
+                gaiaFromSpatiaLiteBlobWkb((const unsigned char *) blob, size);
+              if (g == NULL)
+                goto error;
+              if (g->FirstPoint == NULL)
+                goto error;
+              *x = g->FirstPoint->X;
+              *y = g->FirstPoint->Y;
+              ok = 1;
+            }
+      } else
+        goto error;
+    }
+  if (!ok)
+    goto error;
+  sqlite3_finalize(stmt);
+  gaiaFreeGeomColl(geom);
+  return;
+
+error:
+  if (stmt != NULL)
+    sqlite3_finalize(stmt);
+  if (geom != NULL)
+    gaiaFreeGeomColl(geom);
+  *x = 250.0;
+  *y = 150.0;
+}
+
+void SimpleTextSymbolizerDialog::CreateLineArray(double perpendicular_offset,
+                                                 int *points, double **x,
+                                                 double **y, int generalize)
+{
+// creating the X and Y arrays required by rl2_graph_draw_warped_text()
+  double *xx;
+  double *yy;
+  gaiaLinestringPtr ln;
+  gaiaGeomCollPtr geom = PrepareLinestring(perpendicular_offset);
+  if (geom == NULL)
+    goto error;
+
+  ln = geom->FirstLinestring;
+  if (ln == NULL)
+    goto error;
+
+  xx = new double[ln->Points];
+  yy = new double[ln->Points];
+  if (xx == NULL || yy == NULL)
+    {
+      if (xx != NULL)
+        delete[]xx;
+      if (yy != NULL)
+        delete[]yy;
+      goto error;
+    }
+  for (int iv = 0; iv < ln->Points; iv++)
+    {
+      double cx;
+      double cy;
+      gaiaGetPoint(ln->Coords, iv, &cx, &cy);
+      *(xx + iv) = cx;
+      *(yy + iv) = cy;
+    }
+  *points = ln->Points;
+  *x = xx;
+  *y = yy;
+  return;
+
+error:
+  *points = 0;
+  *x = NULL;
+  *y = NULL;
+}
+
+void SimpleTextSymbolizerDialog::UpdatePreviewPage()
+{
+//
+// updating the PREVIEW page
+//
+  const char *sample = "This little piggy went to market";
+  wxRadioBox *backCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_BACKGROUND);
+  switch (PreviewBackground)
+    {
+      case GUI_PREVIEW_BACKGROUND_WHITE:
+        backCtrl->SetSelection(1);
+        break;
+      case GUI_PREVIEW_BACKGROUND_BLACK:
+        backCtrl->SetSelection(2);
+        break;
+      default:
+        backCtrl->SetSelection(0);
+        break;
+    };
+  wxRadioBox *crossCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_CROSSHAIR);
+  if (Crosshair == false)
+    crossCtrl->SetSelection(1);
+  else
+    crossCtrl->SetSelection(0);
+  if (PointPlacement == true)
+    crossCtrl->Enable(true);
+  else
+    crossCtrl->Enable(false);
+  wxRadioBox *reflineCtrl = (wxRadioBox *) FindWindow(ID_SYMBOLIZER_REFLINE);
+  if (ReferenceLine == false)
+    reflineCtrl->SetSelection(1);
+  else
+    reflineCtrl->SetSelection(0);
+  if (PointPlacement == true)
+    {
+      crossCtrl->Enable(true);
+      reflineCtrl->Enable(false);
+  } else
+    {
+      crossCtrl->Enable(false);
+      reflineCtrl->Enable(true);
+    }
+
+  rl2GraphicsContextPtr ctx = NULL;
+  ctx = rl2_graph_create_context(500, 300);
+  if (ctx == NULL)
+    return;
+// transparent background initialization
+  rl2_graph_set_brush(ctx, 255, 255, 255, 0);
+  rl2_graph_draw_rectangle(ctx, -1, -1, 501, 301);
+
+// setting up the Font
+  char facename[1024];
+  strcpy(facename, FontFamily.ToUTF8());
+  rl2GraphicsFontPtr font = rl2_search_TrueType_font(MainFrame->GetSqlite(),
+                                                     MainFrame->
+                                                     GetRL2PrivateData(),
+                                                     facename,
+                                                     FontSize);
+  double aleph = 255.0 * FillOpacity;
+  if (aleph < 0.0)
+    aleph = 0.0;
+  if (aleph > 255.0)
+    aleph = 255.0;
+  unsigned char alpha = aleph;
+  wxColour color = wxNullColour;
+  ColorMapEntry::GetWxColor(FillColor, color);
+  rl2_graph_font_set_color(font, color.Red(), color.Green(), color.Blue(),
+                           alpha);
+  if (HasHalo == true)
+    {
+      // setting optional Halo
+      aleph = 255.0 * HaloOpacity;
+      if (aleph < 0.0)
+        aleph = 0.0;
+      if (aleph > 255.0)
+        aleph = 255.0;
+      alpha = aleph;
+      color = wxNullColour;
+      ColorMapEntry::GetWxColor(HaloColor, color);
+      rl2_graph_font_set_halo(font, HaloRadius, color.Red(), color.Green(),
+                              color.Blue(), alpha);
+    }
+  rl2_graph_set_font(ctx, font);
+
+  if (PointPlacement == true)
+    {
+      // Point Placement
+      rl2_graph_draw_text(ctx, sample, 250.0 + DisplacementX,
+                          150.0 - DisplacementY, Rotation,
+                          AnchorPointX, AnchorPointY);
+  } else
+    {
+      // Line Placement
+      if (ReferenceLine == true)
+        {
+          // drawing the reference Line
+          double array34[] = { 3.0, 4.0 };
+          PrepareLinestringPath(ctx, 0.0);
+          if (PreviewBackground == GUI_PREVIEW_BACKGROUND_CHECKED)
+            rl2_graph_set_dashed_pen(ctx, 107, 142, 35, 255, 3.0,
+                                     RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_BEVEL, 2,
+                                     array34, 0.0);
+          else
+            rl2_graph_set_dashed_pen(ctx, 0x90, 0x90, 0x90, 255, 3.0,
+                                     RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_BEVEL, 2,
+                                     array34, 0.0);
+          PrepareLinestringPath(ctx, 0.0);
+          rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
+          if (PerpendicularOffset != 0.0)
+            {
+              // drawing the offset line
+              double array23[] = { 2.0, 3.0 };
+              if (PreviewBackground == GUI_PREVIEW_BACKGROUND_CHECKED)
+                rl2_graph_set_dashed_pen(ctx, 107, 142, 35, 255, 2.0,
+                                         RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_BEVEL,
+                                         2, array23, 0.0);
+              else
+                rl2_graph_set_dashed_pen(ctx, 0x90, 0x90, 0x90, 255, 2.0,
+                                         RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_BEVEL,
+                                         2, array23, 0.0);
+              PrepareLinestringPath(ctx, 0.0);
+              PrepareLinestringPath(ctx, PerpendicularOffset);
+              rl2_graph_stroke_path(ctx, RL2_CLEAR_PATH);
+            }
+        }
+      if (IsAligned == false)
+        {
+          // text is always horizontal (not aligned to the line)
+          double cx;
+          double cy;
+          GetLineCenterPoint(PerpendicularOffset, &cx, &cy);
+          rl2_graph_draw_text(ctx, sample, cx, cy, 0.0, 0.5, 0.5);
+      } else
+        {
+          // text aligned to the line
+          int repeated = 1;
+          int generalize = 0;
+          if (IsRepeated == false)
+            repeated = 0;
+          if (GeneralizeLine == false)
+            generalize = 0;
+          int points;
+          double *x_array;
+          double *y_array;
+          CreateLineArray(PerpendicularOffset, &points, &x_array, &y_array,
+                          generalize);
+          if (x_array != NULL && y_array != NULL)
+            {
+              rl2_graph_draw_warped_text(MainFrame->GetSqlite(), ctx, sample,
+                                         points, x_array, y_array, InitialGap,
+                                         Gap, repeated);
+              delete[]x_array;
+              delete[]y_array;
+            }
+        }
+    }
+  // destroying the Font
+  rl2_graph_release_font(ctx);
+  rl2_graph_destroy_font(font);
+
+// creating the RGB and Alpha arrays
+  int half_transparency = 0;
+  unsigned char *rgb_array = rl2_graph_get_context_rgb_array(ctx);
+  unsigned char *alpha_array =
+    rl2_graph_get_context_alpha_array(ctx, &half_transparency);
+  rl2_graph_destroy_context(ctx);
+  if (rgb_array == NULL || alpha_array == NULL)
+    {
+      if (rgb_array != NULL)
+        free(rgb_array);
+      if (alpha_array != NULL)
+        free(alpha_array);
+      return;
+    }
+// creating the Preview from RGB and Alpha arrays
+  wxImage img(500, 300);
+  img.SetData(rgb_array);
+  img.SetAlpha(alpha_array);
+  wxBitmap bmp(img);
+  wxBitmap bmp2;
+  wxBrush brush;
+  wxMemoryDC dc;
+  wxBitmap white = wxBitmap(500, 300);
+  wxBitmap black = wxBitmap(500, 300);
+  switch (PreviewBackground)
+    {
+      case GUI_PREVIEW_BACKGROUND_WHITE:
+        dc.SelectObject(white);
+        brush = wxBrush(wxColour(255, 255, 255));
+        dc.SetBrush(brush);
+        dc.DrawRectangle(0, 0, 500, 300);
+        dc.SelectObject(wxNullBitmap);
+        bmp2 =
+          white.GetSubBitmap(wxRect(0, 0, white.GetWidth(), white.GetHeight()));
+        break;
+      case GUI_PREVIEW_BACKGROUND_BLACK:
+        dc.SelectObject(black);
+        brush = wxBrush(wxColour(0, 0, 0));
+        dc.SetBrush(brush);
+        dc.DrawRectangle(0, 0, 500, 300);
+        dc.SelectObject(wxNullBitmap);
+        bmp2 =
+          black.GetSubBitmap(wxRect(0, 0, black.GetWidth(), black.GetHeight()));
+        break;
+      default:
+        bmp2 =
+          PreviewBackBitmap.GetSubBitmap(wxRect
+                                         (0, 0, PreviewBackBitmap.GetWidth(),
+                                          PreviewBackBitmap.GetHeight()));
+        break;
+    };
+// printing the Preview over the currently selected background
+  dc.SelectObject(bmp2);
+  dc.DrawBitmap(bmp, 0, 0, true);
+  if (PointPlacement == true && Crosshair == true)
+    {
+      // printing the Crosshair over the preview
+      wxColour color = wxColour(255, 255, 255);
+      if (PreviewBackground == GUI_PREVIEW_BACKGROUND_BLACK)
+        color = wxColour(0, 0, 0);
+      dc.SetPen(wxPen(color, 3));
+      dc.DrawLine(250 + DisplacementX, 0, 250 + DisplacementX, 300);
+      dc.DrawLine(0, 150 - DisplacementY, 500, 150 - DisplacementY);
+      color = wxColour(0, 0, 0);
+      if (PreviewBackground == GUI_PREVIEW_BACKGROUND_BLACK)
+        color = wxColour(255, 255, 255);
+      dc.SetPen(wxPen(color, 1));
+      dc.DrawLine(250 + DisplacementX, 0, 250 + DisplacementX, 300);
+      dc.DrawLine(0, 150 - DisplacementY, 500, 150 - DisplacementY);
+      color = wxColour(0, 0, 0);
+      if (PreviewBackground == GUI_PREVIEW_BACKGROUND_BLACK)
+        color = wxColour(255, 255, 255);
+      dc.SetPen(wxPen(color, 5));
+      dc.DrawLine(248, 150, 252, 150);
+      dc.DrawLine(250, 148, 250, 152);
+      color = wxColour(255, 0, 0);
+      dc.SetPen(wxPen(color, 3));
+      dc.DrawLine(249, 150, 251, 150);
+      dc.DrawLine(250, 149, 250, 151);
+    }
+  dc.SelectObject(wxNullBitmap);
+// updating the GUI Preview
+  SymbolizerPreview *previewCtrl =
+    (SymbolizerPreview *) FindWindow(ID_SYMBOLIZER_PREVIEW);
+  previewCtrl->SetBitmap(bmp2);
+}
+
+void SimpleTextSymbolizerDialog::OnPageChanging(wxNotebookEvent & event)
+{
+//
+// TAB/PAGE selection changing
+//
+  bool ret;
+  switch (event.GetOldSelection())
+    {
+      case 0:
+        ret = RetrieveMainPage();
+        break;
+      case 1:
+        ret = RetrieveFontPage();
+        break;
+      case 2:
+        ret = RetrievePlacementPage();
+        break;
+      case 3:
+        ret = RetrievePreviewPage();
+        break;
+    };
+  if (ret != true)
+    event.Veto();
+}
+
+void SimpleTextSymbolizerDialog::OnPageChanged(wxNotebookEvent & event)
+{
+//
+// TAB/PAGE selection changed
+//
+  switch (event.GetSelection())
+    {
+      case 0:
+        UpdateMainPage();
+        break;
+      case 1:
+        UpdateFontPage();
+        break;
+      case 2:
+        UpdatePlacementPage();
+        break;
+      case 3:
+        UpdatePreviewPage();
+        break;
+    };
+}
+
+char *SimpleTextSymbolizerDialog::DoCreateFeatureTypeXML()
+{
+//
+// creating the SLD/SE (XML) code - Feature Type
+//
+  char *str;
+  const char *cstr;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<FeatureTypeStyle version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Rule>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (MinScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MinScaleDenominator>%1.2f</MinScaleDenominator>\r\n", prev,
+         MinScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  if (MaxScale == true)
+    {
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t<MaxScaleDenominator>%1.2f</MaxScaleDenominator>\r\n", prev,
+         MaxScaleDenominator);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  switch (Uom)
+    {
+      case GUI_UOM_METRE:
+        cstr = "http://www.opengeospatial.org/se/units/metre";
+        break;
+      case GUI_UOM_INCH:
+        cstr = "http://www.opengeospatial.org/se/units/inch";
+        break;
+      default:
+        cstr = "http://www.opengeospatial.org/se/units/pixel";
+        break;
+    };
+  xml = sqlite3_mprintf("%s\t\t<TextSymbolizer uom=\"%s\">\r\n", prev, cstr);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Label.ToUTF8()) + 1];
+  strcpy(str, Label.ToUTF8());
+  xml = sqlite3_mprintf("%s\t\t\t<Label>%s</Label>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t<Font>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(FontFamily.ToUTF8()) + 1];
+  strcpy(str, FontFamily.ToUTF8());
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t\t\t<SvgParameter name=\"font-family\">%s</SvgParameter>\r\n", prev,
+     str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (FontStyle == RL2_FONTSTYLE_ITALIC)
+    xml =
+      sqlite3_mprintf
+      ("%s\t\t\t\t<SvgParameter name=\"font-style\">italic</SvgParameter>\r\n",
+       prev);
+  else if (FontStyle == RL2_FONTSTYLE_OBLIQUE)
+    xml =
+      sqlite3_mprintf
+      ("%s\t\t\t\t<SvgParameter name=\"font-style\">oblique</SvgParameter>\r\n",
+       prev);
+  else
+    xml =
+      sqlite3_mprintf
+      ("%s\t\t\t\t<SvgParameter name=\"font-style\">normal</SvgParameter>\r\n",
+       prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (FontWeight == RL2_FONTWEIGHT_BOLD)
+    xml =
+      sqlite3_mprintf
+      ("%s\t\t\t\t<SvgParameter name=\"font-weight\">bold</SvgParameter>\r\n",
+       prev);
+  else
+    xml =
+      sqlite3_mprintf
+      ("%s\t\t\t\t<SvgParameter name=\"font-weight\">normal</SvgParameter>\r\n",
+       prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t\t\t<SvgParameter name=\"font-size\">%1.2f</SvgParameter>\r\n",
+     prev, FontSize);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</Font>\r\n", prev, str);
+  sqlite3_free(prev);
+  prev = xml;
+
+  xml = sqlite3_mprintf("%s\t\t\t<LabelPlacement>\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (PointPlacement == true)
+    {
+      // PointPlacement
+      xml = sqlite3_mprintf("%s\t\t\t\t<PointPlacement>\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (AnchorPointX != 0.5 || AnchorPointY != 0.5)
+        {
+          xml = sqlite3_mprintf("%s\t\t\t\t\t<AnchorPoint>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t<AnchorPointX>%1.4f</AnchorPointX>\r\n", prev,
+             AnchorPointX);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t<AnchorPointY>%1.4f</AnchorPointY>\r\n", prev,
+             AnchorPointY);
+          sqlite3_free(prev);
+          prev = xml;
+          xml = sqlite3_mprintf("%s\t\t\t\t\t</AnchorPoint>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (DisplacementX != 0.0 || DisplacementY != 0.0)
+        {
+          xml = sqlite3_mprintf("%s\t\t\t\t\t<Displacement>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t<DisplacementX>%1.4f</DisplacementX>\r\n", prev,
+             DisplacementX);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t\t<DisplacementY>%1.4f</DisplacementY>\r\n", prev,
+             DisplacementY);
+          sqlite3_free(prev);
+          prev = xml;
+          xml = sqlite3_mprintf("%s\t\t\t\t\t</Displacement>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Rotation != 0.0)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t<Rotation>%1.2f</Rotation>\r\n", prev, Rotation);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t\t\t</PointPlacement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+  } else
+    {
+      // LinePlacement
+      xml = sqlite3_mprintf("%s\t\t\t\t<LinePlacement>\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (PerpendicularOffset != 0.0)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t<PerpendicularOffset>%1.4f</PerpendicularOffset>\r\n",
+             prev, PerpendicularOffset);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (IsRepeated == true)
+        {
+          // Repeated: InitialGap and Gap
+          xml =
+            sqlite3_mprintf("%s\t\t\t\t\t<IsRepeated>true</IsRepeated>\r\n",
+                            prev);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t<InitialGap>%1.4f</InitialGap>\r\n", prev,
+             InitialGap);
+          sqlite3_free(prev);
+          prev = xml;
+          xml = sqlite3_mprintf("%s\t\t\t\t\t<Gap>%1.4f</Gap>\r\n", prev, Gap);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (IsAligned == true)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t<IsAligned>true</IsAligned>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (GeneralizeLine == true)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t\t<GeneralizeLine>true</GeneralizeLine>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t\t\t</LinePlacement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t\t</LabelPlacement>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (HasHalo == true)
+    {
+      // Halo
+      xml = sqlite3_mprintf("%s\t\t\t<Halo>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t\t\t<Radius>%1.2f</Radius>\r\n", prev,
+                        HaloRadius);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t\t\t<Fill>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(HaloColor.ToUTF8()) + 1];
+      strcpy(str, FillColor.ToUTF8());
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t\t\t<SvgParameter name=\"fill\">%s</SvgParameter>\r\n",
+         prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t\t\t</Fill>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t\t</Halo>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t\t\t<Fill>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(HaloColor.ToUTF8()) + 1];
+  strcpy(str, FillColor.ToUTF8());
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t\t\t<SvgParameter name=\"fill\">%s</SvgParameter>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t\t\t<SvgParameter name=\"fill-opacity\">%1.2f</SvgParameter>\r\n",
+     prev, FillOpacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t\t</Fill>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t\t</TextSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</Rule>\r\n</FeatureTypeStyle>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+char *SimpleTextSymbolizerDialog::DoCreateSymbolizerXML()
+{
+//
+// creating the SLD/SE (XML) code - TextSymbolizer
+//
+  char *str;
+  const char *cstr;
+  char *prev;
+  char *xml = sqlite3_mprintf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
+  prev = xml;
+  xml = sqlite3_mprintf("%s<TextSymbolizer version=\"1.1.0\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%sxsi:schemaLocation=\"http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/Symbolizer.xsd\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf
+    ("%sxmlns=\"http://www.opengis.net/se\" xmlns:ogc=\"http://www.opengis.net/ogc\" ",
+     prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf("%sxmlns:xlink=\"http://www.w3.org/1999/xlink\" ", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  switch (Uom)
+    {
+      case GUI_UOM_METRE:
+        cstr = "http://www.opengeospatial.org/se/units/metre";
+        break;
+      case GUI_UOM_INCH:
+        cstr = "http://www.opengeospatial.org/se/units/inch";
+        break;
+      default:
+        cstr = "http://www.opengeospatial.org/se/units/pixel";
+        break;
+    };
+  xml =
+    sqlite3_mprintf
+    ("%sxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" uom=\"%s\">\r\n",
+     prev, cstr);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(Name.ToUTF8()) + 1];
+  strcpy(str, Name.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Name>%s</Name>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (Title.Len() > 0 || Abstract.Len() > 0)
+    {
+      xml = sqlite3_mprintf("%s\t<Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (Title.Len() > 0)
+        {
+          str = new char[strlen(Title.ToUTF8()) + 1];
+          strcpy(str, Title.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Title>%s</Title>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Abstract.Len() > 0)
+        {
+          str = new char[strlen(Abstract.ToUTF8()) + 1];
+          strcpy(str, Abstract.ToUTF8());
+          xml = sqlite3_mprintf("%s\t\t<Abstract>%s</Abstract>\r\n", prev, str);
+          delete[]str;
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t</Description>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  str = new char[strlen(Label.ToUTF8()) + 1];
+  strcpy(str, Label.ToUTF8());
+  xml = sqlite3_mprintf("%s\t<Label>%s</Label>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t<Font>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(FontFamily.ToUTF8()) + 1];
+  strcpy(str, FontFamily.ToUTF8());
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t<SvgParameter name=\"font-family\">%s</SvgParameter>\r\n", prev,
+     str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  if (FontStyle == RL2_FONTSTYLE_ITALIC)
+    xml =
+      sqlite3_mprintf
+      ("%s\t\t<SvgParameter name=\"font-style\">italic</SvgParameter>\r\n",
+       prev);
+  else if (FontStyle == RL2_FONTSTYLE_OBLIQUE)
+    xml =
+      sqlite3_mprintf
+      ("%s\t\t<SvgParameter name=\"font-style\">oblique</SvgParameter>\r\n",
+       prev);
+  else
+    xml =
+      sqlite3_mprintf
+      ("%s\t\t<SvgParameter name=\"font-style\">normal</SvgParameter>\r\n",
+       prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (FontWeight == RL2_FONTWEIGHT_BOLD)
+    xml =
+      sqlite3_mprintf
+      ("%s\t\t<SvgParameter name=\"font-weight\">bold</SvgParameter>\r\n",
+       prev);
+  else
+    xml =
+      sqlite3_mprintf
+      ("%s\t\t<SvgParameter name=\"font-weight\">normal</SvgParameter>\r\n",
+       prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t<SvgParameter name=\"font-size\">%1.2f</SvgParameter>\r\n", prev,
+     FontSize);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</Font>\r\n", prev, str);
+  sqlite3_free(prev);
+  prev = xml;
+
+  xml = sqlite3_mprintf("%s\t<LabelPlacement>\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (PointPlacement == true)
+    {
+      // PointPlacement
+      xml = sqlite3_mprintf("%s\t\t<PointPlacement>\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (AnchorPointX != 0.5 || AnchorPointY != 0.5)
+        {
+          xml = sqlite3_mprintf("%s\t\t\t<AnchorPoint>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf("%s\t\t\t\t<AnchorPointX>%1.4f</AnchorPointX>\r\n",
+                            prev, AnchorPointX);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf("%s\t\t\t\t<AnchorPointY>%1.4f</AnchorPointY>\r\n",
+                            prev, AnchorPointY);
+          sqlite3_free(prev);
+          prev = xml;
+          xml = sqlite3_mprintf("%s\t\t\t</AnchorPoint>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (DisplacementX != 0.0 || DisplacementY != 0.0)
+        {
+          xml = sqlite3_mprintf("%s\t\t\t<Displacement>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<DisplacementX>%1.4f</DisplacementX>\r\n", prev,
+             DisplacementX);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t\t<DisplacementY>%1.4f</DisplacementY>\r\n", prev,
+             DisplacementY);
+          sqlite3_free(prev);
+          prev = xml;
+          xml = sqlite3_mprintf("%s\t\t\t</Displacement>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (Rotation != 0.0)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t<Rotation>%1.2f</Rotation>\r\n", prev, Rotation);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t</PointPlacement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+  } else
+    {
+      // LinePlacement
+      xml = sqlite3_mprintf("%s\t\t<LinePlacement>\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      if (PerpendicularOffset != 0.0)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t<PerpendicularOffset>%1.4f</PerpendicularOffset>\r\n",
+             prev, PerpendicularOffset);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (IsRepeated == true)
+        {
+          // Repeated: InitialGap and Gap
+          xml =
+            sqlite3_mprintf("%s\t\t\t<IsRepeated>true</IsRepeated>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t<InitialGap>%1.4f</InitialGap>\r\n", prev, InitialGap);
+          sqlite3_free(prev);
+          prev = xml;
+          xml = sqlite3_mprintf("%s\t\t\t<Gap>%1.4f</Gap>\r\n", prev, Gap);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (IsAligned == true)
+        {
+          xml =
+            sqlite3_mprintf("%s\t\t\t<IsAligned>true</IsAligned>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      if (GeneralizeLine == true)
+        {
+          xml =
+            sqlite3_mprintf
+            ("%s\t\t\t<GeneralizeLine>true</GeneralizeLine>\r\n", prev);
+          sqlite3_free(prev);
+          prev = xml;
+        }
+      xml = sqlite3_mprintf("%s\t\t</LinePlacement>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t</LabelPlacement>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  if (HasHalo == true)
+    {
+      // Halo
+      xml = sqlite3_mprintf("%s\t<Halo>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml =
+        sqlite3_mprintf("%s\t\t<Radius>%1.2f</Radius>\r\n", prev, HaloRadius);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t<Fill>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      str = new char[strlen(HaloColor.ToUTF8()) + 1];
+      strcpy(str, FillColor.ToUTF8());
+      xml =
+        sqlite3_mprintf
+        ("%s\t\t\t<SvgParameter name=\"fill\">%s</SvgParameter>\r\n",
+         prev, str);
+      delete[]str;
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t\t</Fill>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+      xml = sqlite3_mprintf("%s\t</Halo>\r\n", prev);
+      sqlite3_free(prev);
+      prev = xml;
+    }
+  xml = sqlite3_mprintf("%s\t<Fill>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  str = new char[strlen(HaloColor.ToUTF8()) + 1];
+  strcpy(str, FillColor.ToUTF8());
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t<SvgParameter name=\"fill\">%s</SvgParameter>\r\n", prev, str);
+  delete[]str;
+  sqlite3_free(prev);
+  prev = xml;
+  xml =
+    sqlite3_mprintf
+    ("%s\t\t<SvgParameter name=\"fill-opacity\">%1.2f</SvgParameter>\r\n",
+     prev, FillOpacity);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s\t</Fill>\r\n", prev);
+  sqlite3_free(prev);
+  prev = xml;
+  xml = sqlite3_mprintf("%s</TextSymbolizer>\r\n", prev);
+  sqlite3_free(prev);
+  return xml;
+}
+
+void SimpleTextSymbolizerDialog::OnInsert(wxCommandEvent & WXUNUSED(event))
+{
+//
+// inserting the VectorSymbolizer into the DBMS
+//
+  switch (GetBookCtrl()->GetSelection())
+    {
+      case 0:
+        RetrieveMainPage();
+        break;
+      case 1:
+        RetrieveFontPage();
+        break;
+      case 2:
+        RetrievePlacementPage();
+        break;
+      case 3:
+        RetrievePreviewPage();
+        break;
+    };
+  if (FinalValidityCheck() == false)
+    {
+      GetBookCtrl()->ChangeSelection(0);
+      return;
+    }
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateFeatureTypeXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  if (MainFrame->DoInsertVectorSymbolizer(xml) == true)
+    wxMessageBox(wxT
+                 ("SLD/SE VectorSymbolizer successfully registered into the DBMS"),
+                 wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
+  wxDialog::EndModal(wxID_OK);
+}
+
+void SimpleTextSymbolizerDialog::OnExport(wxCommandEvent & WXUNUSED(event))
+{
+//
+// exporting the VectorSymbolizer as an external file
+//
+  int ret;
+  wxString path;
+  wxString lastDir;
+  switch (GetBookCtrl()->GetSelection())
+    {
+      case 0:
+        RetrieveMainPage();
+        break;
+      case 1:
+        RetrieveFontPage();
+        break;
+      case 2:
+        RetrievePlacementPage();
+        break;
+      case 3:
+        RetrievePreviewPage();
+        break;
+    };
+  if (FinalValidityCheck() == false)
+    {
+      GetBookCtrl()->ChangeSelection(0);
+      return;
+    }
+  wxFileDialog fileDialog(this,
+                          wxT("Exporting an SLD/SE TextSymbolizer to a file"),
+                          wxT(""), Name + wxT(".xml"),
+                          wxT("XML Document|*.xml|All files (*.*)|*.*"),
+                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
+                          wxDefaultSize, wxT("filedlg"));
+  lastDir = MainFrame->GetLastDirectory();
+  if (lastDir.Len() >= 1)
+    fileDialog.SetDirectory(lastDir);
+  ret = fileDialog.ShowModal();
+  if (ret == wxID_OK)
+    {
+      wxFileName file(fileDialog.GetPath());
+      path = file.GetPath();
+      path += file.GetPathSeparator();
+      path += file.GetName();
+      lastDir = file.GetPath();
+      path = fileDialog.GetPath();
+      FILE *out = fopen(path.ToUTF8(), "wb");
+      if (out == NULL)
+        wxMessageBox(wxT("ERROR: unable to create:\n\n\"") + path + wxT("\""),
+                     wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
+      else
+        {
+          char *xml;
+          if (MinScale == true || MaxScale == true)
+            xml = DoCreateFeatureTypeXML();
+          else
+            xml = DoCreateSymbolizerXML();
+          fwrite(xml, 1, strlen(xml), out);
+          sqlite3_free(xml);
+          fclose(out);
+          wxMessageBox(wxT
+                       ("SLD/SE TextSymbolizer successfully saved into:\n\n\"")
+                       + path + wxT("\""), wxT("spatialite_gui"),
+                       wxOK | wxICON_INFORMATION, this);
+        }
+    }
+  wxDialog::EndModal(wxID_OK);
+}
+
+void SimpleTextSymbolizerDialog::OnCopy(wxCommandEvent & WXUNUSED(event))
+{
+//
+// Copying the VectorSymbolizer into the Clipboard 
+//
+  switch (GetBookCtrl()->GetSelection())
+    {
+      case 0:
+        RetrieveMainPage();
+        break;
+      case 1:
+        RetrieveFontPage();
+        break;
+      case 2:
+        RetrievePlacementPage();
+        break;
+      case 3:
+        RetrievePreviewPage();
+        break;
+    };
+  if (FinalValidityCheck() == false)
+    {
+      GetBookCtrl()->ChangeSelection(0);
+      return;
+    }
+  char *xml;
+  if (MinScale == true || MaxScale == true)
+    xml = DoCreateFeatureTypeXML();
+  else
+    xml = DoCreateSymbolizerXML();
+  wxString XMLstring = wxString::FromUTF8(xml);
+  if (wxTheClipboard->Open())
+    {
+      wxTheClipboard->SetData(new wxTextDataObject(XMLstring));
+      wxTheClipboard->Close();
+    }
+}
+
+void SimpleTextSymbolizerDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
+{
+//
+// all done: 
+//
+  wxDialog::EndModal(wxID_OK);
+}
diff --git a/Wfs.cpp b/Wfs.cpp
index cf5ed64..152be25 100644
--- a/Wfs.cpp
+++ b/Wfs.cpp
@@ -27,7 +27,7 @@
 
 #include "wx/clipbrd.h"
 
-bool WfsDialog::Create(MyFrame * parent)
+bool WfsDialog::Create(MyFrame * parent, wxString & wfs_url, wxString & proxy)
 {
 //
 // creating the dialog
@@ -38,6 +38,14 @@ bool WfsDialog::Create(MyFrame * parent)
     return false;
   CurrentEvtRow = -1;
   CurrentEvtColumn = -1;
+  WfsGetCapabilitiesURL = wfs_url;
+  if (WfsGetCapabilitiesURL.Len() == 0)
+    WfsGetCapabilitiesURL = wxT("http://");
+  HttpProxy = proxy;
+  if (HttpProxy.Len() == 0)
+    ProxyEnabled = false;
+  else
+    ProxyEnabled = true;
 // populates individual controls
   CreateControls();
 // sets dialog sizer
@@ -59,6 +67,23 @@ void WfsDialog::CreateControls()
   this->SetSizer(topSizer);
   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
   topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
+// HTTP Proxy
+  wxStaticBox *proxyBox = new wxStaticBox(this, wxID_STATIC,
+                                          wxT("HTTP Proxy"),
+                                          wxDefaultPosition,
+                                          wxDefaultSize);
+  wxBoxSizer *proxyBoxSizer = new wxStaticBoxSizer(proxyBox, wxHORIZONTAL);
+  boxSizer->Add(proxyBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2);
+  wxCheckBox *enableProxyCtrl = new wxCheckBox(this, ID_WFS_ENABLE_PROXY,
+                                               wxT("Enable"),
+                                               wxDefaultPosition,
+                                               wxDefaultSize);
+  enableProxyCtrl->SetValue(ProxyEnabled);
+  proxyBoxSizer->Add(enableProxyCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  wxTextCtrl *proxyCtrl = new wxTextCtrl(this, ID_WFS_PROXY, HttpProxy,
+                                         wxDefaultPosition, wxSize(600, 22));
+  proxyBoxSizer->Add(proxyCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+  proxyCtrl->Enable(ProxyEnabled);
 // URL group box
   wxStaticBox *urlBox = new wxStaticBox(this, wxID_STATIC,
                                         wxT("WFS URL - GetCapabilities"),
@@ -69,7 +94,7 @@ void WfsDialog::CreateControls()
 // First row: GetCapabilities URL
   wxBoxSizer *urlSizer = new wxBoxSizer(wxVERTICAL);
   urlBoxSizer->Add(urlSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
-  wxTextCtrl *urlCtrl = new wxTextCtrl(this, ID_WFS_URL, wxT("http://"),
+  wxTextCtrl *urlCtrl = new wxTextCtrl(this, ID_WFS_URL, WfsGetCapabilitiesURL,
                                        wxDefaultPosition, wxSize(680, 22));
   urlSizer->Add(urlCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
 // command buttons
@@ -131,13 +156,15 @@ void WfsDialog::CreateControls()
 // First row: WFS options
   wxBoxSizer *wfsSizer = new wxBoxSizer(wxHORIZONTAL);
   lyrBoxSizer->Add(wfsSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
-  wxString ver[2];
-  ver[0] = wxT("WFS &1.0.0");
-  ver[1] = wxT("WFS &1.1.0");
+  wxString ver[4];
+  ver[0] = wxT("&1.0.0");
+  ver[1] = wxT("&1.1.0");
+  ver[2] = wxT("&2.0.0");
+  ver[3] = wxT("&2.0.2");
   wxRadioBox *versionBox = new wxRadioBox(this, ID_WFS_VERSION,
                                           wxT("WFS &Version"),
                                           wxDefaultPosition,
-                                          wxDefaultSize, 2,
+                                          wxDefaultSize, 4,
                                           ver, 2,
                                           wxRA_SPECIFY_ROWS);
   versionBox->Enable(false);
@@ -233,7 +260,7 @@ void WfsDialog::CreateControls()
   rtreeCtrl->SetValue(false);
   rtreeCtrl->Enable(false);
   dbSizer->Add(rtreeCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
-// fifth row:  status and start button
+// fifth row: status and start button
   wxBoxSizer *statusSizer = new wxBoxSizer(wxHORIZONTAL);
   lyrBoxSizer->Add(statusSizer, 0, wxALIGN_LEFT | wxALL, 0);
   wxButton *load = new wxButton(this, ID_WFS_LOAD, wxT("&Load data"));
@@ -251,6 +278,8 @@ void WfsDialog::CreateControls()
           (wxObjectEventFunction) & WfsDialog::OnLeftClick);
   Connect(wxID_ANY, wxEVT_GRID_CELL_RIGHT_CLICK,
           (wxObjectEventFunction) & WfsDialog::OnRightClick);
+  Connect(ID_WFS_ENABLE_PROXY, wxEVT_COMMAND_CHECKBOX_CLICKED,
+          (wxObjectEventFunction) & WfsDialog::OnProxy);
   Connect(ID_WFS_PAGING, wxEVT_COMMAND_RADIOBOX_SELECTED,
           (wxObjectEventFunction) & WfsDialog::OnPagingChanged);
   Connect(ID_WFS_CATALOG, wxEVT_COMMAND_BUTTON_CLICKED,
@@ -285,7 +314,7 @@ void WfsDialog::OnRefreshTimer(wxTimerEvent & WXUNUSED(event))
 //
   if (Params.GetProgressCount() > Params.GetLastProgressCount())
     {
-      Params.SetLastProgressCount(Params.GetProgressCount());
+      Params.SetLastProgressCount();
       ProgressUpdate(Params.GetProgressCount());
     }
   Progress->Show(true);
@@ -360,8 +389,21 @@ void WfsDialog::SelectLayer()
   comboCtrl->SetSelection(0);
   comboCtrl->Enable(true);
   wxRadioBox *versionBox = (wxRadioBox *) FindWindow(ID_WFS_VERSION);
+  const char *version = get_wfs_version(Catalog);
   versionBox->Enable(true);
-  versionBox->SetSelection(1);
+  if (version == NULL)
+    versionBox->SetSelection(1);
+  else
+    {
+      if (strcmp(version, "1.0.0") == 0)
+        versionBox->SetSelection(0);
+      else if (strcmp(version, "2.0.0") == 0)
+        versionBox->SetSelection(2);
+      else if (strcmp(version, "2.0.2") == 0)
+        versionBox->SetSelection(3);
+      else
+        versionBox->SetSelection(1);
+    }
   wxTextCtrl *maxCtrl = (wxTextCtrl *) FindWindow(ID_WFS_MAX);
   maxCtrl->SetValue(wxT("100"));
   maxCtrl->Enable(true);
@@ -414,7 +456,28 @@ void WfsDialog::SelectLayer()
   rtreeCtrl->SetValue(true);
   rtreeCtrl->Enable(true);
   wxCheckBox *swapCtrl = (wxCheckBox *) FindWindow(ID_WFS_SWAP);
-  swapCtrl->SetValue(false);
+  long srid = -1;
+  comboCtrl = (wxComboBox *) FindWindow(ID_WFS_SRID);
+  int idSel = comboCtrl->GetSelection();
+  if (idSel != wxNOT_FOUND)
+    {
+      if (comboCtrl->GetString(idSel).ToLong(&srid) == false)
+        srid = -1;
+    }
+  if (srid > 0)
+    {
+      int flipped = 0;
+      if (!srid_has_flipped_axes(MainFrame->GetSqlite(), srid, &flipped))
+        swapCtrl->SetValue(false);
+      else
+        {
+          if (flipped)
+            swapCtrl->SetValue(true);
+          else
+            swapCtrl->SetValue(false);
+        }
+  } else
+    swapCtrl->SetValue(false);
   swapCtrl->Enable(true);
   wxButton *load = (wxButton *) FindWindow(ID_WFS_LOAD);
   load->Enable(true);
@@ -455,18 +518,19 @@ void WfsDialog::OnRightClick(wxGridEvent & event)
 //
 // right click on some cell [mouse action]
 //
-  wxMenu *menu = new wxMenu();
+  wxMenu menu;
   wxMenuItem *menuItem;
   wxPoint pt = event.GetPosition();
   CurrentEvtRow = event.GetRow();
   CurrentEvtColumn = event.GetCol();
   menuItem =
-    new wxMenuItem(menu, Wfs_Layer, wxT("Select as the current WFS &Layer"));
-  menu->Append(menuItem);
-  menu->AppendSeparator();
-  menuItem = new wxMenuItem(menu, Wfs_Copy, wxT("&Copy the whole WFS Catalog"));
-  menu->Append(menuItem);
-  WfsView->PopupMenu(menu, pt);
+    new wxMenuItem(&menu, Wfs_Layer, wxT("Select as the current WFS &Layer"));
+  menu.Append(menuItem);
+  menu.AppendSeparator();
+  menuItem =
+    new wxMenuItem(&menu, Wfs_Copy, wxT("&Copy the whole WFS Catalog"));
+  menu.Append(menuItem);
+  WfsView->PopupMenu(&menu, pt);
 }
 
 void WfsDialog::OnPagingChanged(wxCommandEvent & WXUNUSED(event))
@@ -631,6 +695,10 @@ void WfsDialog::OnLoadFromWfs(wxCommandEvent & WXUNUSED(event))
   const char *version = "1.1.0";
   if (versionCtrl->GetSelection() == 0)
     version = "1.0.0";
+  else if (versionCtrl->GetSelection() == 2)
+    version = "2.0.0";
+  else if (versionCtrl->GetSelection() == 3)
+    version = "2.0.2";
   wxString table = tableCtrl->GetValue();
   if (table.Len() < 1)
     {
@@ -657,15 +725,31 @@ void WfsDialog::OnLoadFromWfs(wxCommandEvent & WXUNUSED(event))
   char *xalt_describe = get_wfs_describe_url(Catalog, xname, version);
   wxString alt_describe = wxString::FromUTF8(xalt_describe);
   free(xalt_describe);
-  char *err_msg = NULL;
-  int rows;
   ::wxBeginBusyCursor();
   ProgressWait();
   Params.Initialize(this, MainFrame->GetSqlite(), url, alt_describe, name,
                     swap_axes, table, pk, rtree, page, extra, WfsCallback);
   ProgressTimer->Start(500, wxTIMER_ONE_SHOT);
   Enable(false);
-
+  if (ProxyEnabled == true && HttpProxy.Len() > 0)
+    {
+      // setting up the HTTP Proxy
+#ifdef _WIN32
+      char *p = new char[HttpProxy.Len() + 1];
+      strcpy(p, HttpProxy.ToUTF8());
+      char *proxy_str = sqlite3_mprintf("http_proxy=%s", p);
+      delete[]p;
+      PreviousHttpProxy = wxString::FromUTF8(getenv("http_proxy"));
+      _putenv(proxy_str);
+      sqlite3_free(proxy_str);
+#else /* not Windows */
+      char *proxy_str = new char[HttpProxy.Len() + 1];
+      strcpy(proxy_str, HttpProxy.ToUTF8());
+      PreviousHttpProxy = wxString::FromUTF8(getenv("http_proxy"));
+      setenv("http_proxy", proxy_str, 1);
+      delete[]proxy_str;
+#endif
+    }
 #ifdef _WIN32
   thread_handle = CreateThread(NULL, 0, DoExecuteWfs, &Params, 0, &dwThreadId);
   SetThreadPriority(thread_handle, THREAD_PRIORITY_IDLE);
@@ -738,6 +822,30 @@ void WfsDialog::OnThreadFinished(wxCommandEvent & WXUNUSED(event))
     }
   if (err_msg)
     free(err_msg);
+  if (ProxyEnabled == true)
+    {
+#ifdef _WIN32
+      _putenv("http_proxy=");
+#else /* not Windows */
+      unsetenv("http_proxy");
+#endif
+      if (PreviousHttpProxy.Len() > 0)
+        {
+#ifdef _WIN32
+          char *p = new char[PreviousHttpProxy.Len() + 1];
+          strcpy(p, PreviousHttpProxy.ToUTF8());
+          char *proxy_str = sqlite3_mprintf("http_proxy=%s", p);
+          delete[]p;
+          _putenv(proxy_str);
+          sqlite3_free(proxy_str);
+#else /* not Windows */
+          char *proxy_str = new char[PreviousHttpProxy.Len() + 1];
+          strcpy(proxy_str, PreviousHttpProxy.ToUTF8());
+          setenv("http_proxy", proxy_str, 1);
+          delete[]proxy_str;
+#endif
+        }
+    }
 }
 
 void WfsDialog::OnCatalog(wxCommandEvent & WXUNUSED(event))
@@ -745,19 +853,56 @@ void WfsDialog::OnCatalog(wxCommandEvent & WXUNUSED(event))
 //
 // attempting to create a WFS Catalog from GetCapabilities
 //
+  wxCheckBox *enableProxyCtrl = (wxCheckBox *) FindWindow(ID_WFS_ENABLE_PROXY);
+  wxTextCtrl *proxyCtrl = (wxTextCtrl *) FindWindow(ID_WFS_PROXY);
+  if (ProxyEnabled == true)
+    {
+      HttpProxy = proxyCtrl->GetValue();
+      if (HttpProxy.Len() == 0)
+        {
+          wxMessageBox(wxT("You must specify some HTTP Proxy URL !!!"),
+                       wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
+          return;
+        }
+    }
   wxTextCtrl *urlCtrl = (wxTextCtrl *) FindWindow(ID_WFS_URL);
   wxButton *catalogBtn = (wxButton *) FindWindow(ID_WFS_CATALOG);
   wxButton *resetBtn = (wxButton *) FindWindow(ID_WFS_RESET);
-  wxString url = urlCtrl->GetValue();
-  if (url.Len() < 1)
+  WfsGetCapabilitiesURL = urlCtrl->GetValue();
+  if (WfsGetCapabilitiesURL.Len() < 1)
     {
       wxMessageBox(wxT("You must specify some WFS GetCapabilities URL !!!"),
                    wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
       return;
     }
+  if (WfsGetCapabilitiesURL.EndsWith(wxT("?")))
+    {
+      // auto-completing the GetCapabilities URL
+      WfsGetCapabilitiesURL += wxT("SERVICE=WFS&REQUEST=GetCapabilities");
+      urlCtrl->SetValue(WfsGetCapabilitiesURL);
+    }
   char xurl[1024];
   char *err_msg;
-  strcpy(xurl, url.ToUTF8());
+  if (ProxyEnabled == true && HttpProxy.Len() > 0)
+    {
+      // setting up the HTTP Proxy
+#ifdef _WIN32
+      char *p = new char[HttpProxy.Len() + 1];
+      strcpy(p, HttpProxy.ToUTF8());
+      char *proxy_str = sqlite3_mprintf("http_proxy=%s", p);
+      delete[]p;
+      PreviousHttpProxy = wxString::FromUTF8(getenv("http_proxy"));
+      _putenv(proxy_str);
+      sqlite3_free(proxy_str);
+#else /* not Windows */
+      char *proxy_str = new char[HttpProxy.Len() + 1];
+      strcpy(proxy_str, HttpProxy.ToUTF8());
+      PreviousHttpProxy = wxString::FromUTF8(getenv("http_proxy"));
+      setenv("http_proxy", proxy_str, 1);
+      delete[]proxy_str;
+#endif
+    }
+  strcpy(xurl, WfsGetCapabilitiesURL.ToUTF8());
   Catalog = create_wfs_catalog(xurl, &err_msg);
   if (Catalog == NULL)
     {
@@ -766,6 +911,8 @@ void WfsDialog::OnCatalog(wxCommandEvent & WXUNUSED(event))
                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
   } else
     {
+      enableProxyCtrl->Enable(false);
+      proxyCtrl->Enable(false);
       int nLayers = get_wfs_catalog_count(Catalog);
       WfsView->Show(false);
       WfsView->ClearSelection();
@@ -830,6 +977,32 @@ void WfsDialog::OnCatalog(wxCommandEvent & WXUNUSED(event))
     }
   if (err_msg != NULL)
     free(err_msg);
+  if (ProxyEnabled == true)
+    {
+#ifdef _WIN32
+      _putenv("http_proxy=");
+#else /* not Windows */
+      unsetenv("http_proxy");
+#endif
+      if (PreviousHttpProxy.Len() > 0)
+        {
+#ifdef _WIN32
+          char *p = new char[PreviousHttpProxy.Len() + 1];
+          strcpy(p, PreviousHttpProxy.ToUTF8());
+          char *proxy_str = sqlite3_mprintf("http_proxy=%s", p);
+          delete[]p;
+          _putenv(proxy_str);
+          sqlite3_free(proxy_str);
+#else /* not Windows */
+          char *proxy_str = new char[PreviousHttpProxy.Len() + 1];
+          strcpy(proxy_str, PreviousHttpProxy.ToUTF8());
+          setenv("http_proxy", proxy_str, 1);
+          delete[]proxy_str;
+#endif
+        }
+    }
+  MainFrame->SetHttpProxy(HttpProxy);
+  MainFrame->SetWfsGetCapabilitiesURL(WfsGetCapabilitiesURL);
 }
 
 void WfsDialog::OnReset(wxCommandEvent & WXUNUSED(event))
@@ -840,6 +1013,11 @@ void WfsDialog::OnReset(wxCommandEvent & WXUNUSED(event))
   wxTextCtrl *urlCtrl = (wxTextCtrl *) FindWindow(ID_WFS_URL);
   wxButton *catalogBtn = (wxButton *) FindWindow(ID_WFS_CATALOG);
   wxButton *resetBtn = (wxButton *) FindWindow(ID_WFS_RESET);
+  wxCheckBox *enableProxyCtrl = (wxCheckBox *) FindWindow(ID_WFS_ENABLE_PROXY);
+  wxTextCtrl *proxyCtrl = (wxTextCtrl *) FindWindow(ID_WFS_PROXY);
+  enableProxyCtrl->Enable(true);
+  if (ProxyEnabled == true)
+    proxyCtrl->Enable(true);
   if (Catalog != NULL)
     destroy_wfs_catalog(Catalog);
   Catalog = NULL;
@@ -1062,6 +1240,26 @@ void WfsDialog::OnKeyReset(wxCommandEvent & WXUNUSED(event))
   ResetProgress();
 }
 
+void WfsDialog::OnProxy(wxCommandEvent & WXUNUSED(event))
+{
+//
+// enabling/disabling HTTP Proxy
+//
+  wxTextCtrl *proxy = (wxTextCtrl *) FindWindow(ID_WFS_PROXY);
+  if (ProxyEnabled == false)
+    ProxyEnabled = true;
+  else
+    ProxyEnabled = false;
+  proxy->Enable(ProxyEnabled);
+  if (ProxyEnabled == false)
+    {
+      HttpProxy = wxT("");
+      proxy->SetValue(wxT(""));
+    }
+// resetting the libxml2 "nano HTTP" before changing HTTP_PROXY
+  reset_wfs_http_connection();
+}
+
 void WfsDialog::OnQuit(wxCommandEvent & WXUNUSED(event))
 {
 //
diff --git a/aclocal.m4 b/aclocal.m4
index 5e48e24..a482529 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.12.2 -*- Autoconf -*-
+# generated automatically by aclocal 1.15 -*- Autoconf -*-
 
-# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
@@ -219,24 +220,37 @@ m4_popdef([pkg_default])
 m4_popdef([pkg_description])
 ]) dnl PKG_NOARCH_INSTALLDIR
 
-# Copyright (C) 2002-2012 Free Software Foundation, Inc.
+
+# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# -------------------------------------------
+# Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])# PKG_CHECK_VAR
+
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 8
-
 # AM_AUTOMAKE_VERSION(VERSION)
 # ----------------------------
 # Automake X.Y traces this macro to ensure aclocal.m4 has been
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.12'
+[am__api_version='1.15'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.12.2], [],
+m4_if([$1], [1.15], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -252,21 +266,19 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.12.2])dnl
+[AM_AUTOMAKE_VERSION([1.15])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 2
-
 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
 # $ac_aux_dir to '$srcdir/foo'.  In other projects, it is set to
 # '$srcdir', '$srcdir/..', or '$srcdir/../..'.
@@ -306,22 +318,19 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 # configured tree to be moved without reconfiguration.
 
 AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
 ])
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2012 Free Software Foundation, Inc.
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 10
-
 # AM_CONDITIONAL(NAME, SHELL-CONDITION)
 # -------------------------------------
 # Define a conditional.
@@ -347,13 +356,12 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2012 Free Software Foundation, Inc.
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 17
 
 # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
 # written in clear, in which case automake, when reading aclocal.m4,
@@ -539,19 +547,18 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2012 Free Software Foundation, Inc.
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 6
 
 # _AM_OUTPUT_DEPENDENCY_COMMANDS
 # ------------------------------
 AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
 [{
-  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
   case $CONFIG_FILES in
@@ -580,7 +587,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
     DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
     test -z "$DEPDIR" && continue
     am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "am__include" && continue
+    test -z "$am__include" && continue
     am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
     # Find all dependency output files, they are included files with
     # $(DEPDIR) in their names.  We invoke sed twice because it is the
@@ -614,30 +621,23 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
      [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
 ])
 
-# Copyright (C) 1996-2012 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 8
-
-# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
-AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
-
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 19
-
 # This macro actually does too much.  Some checks are only needed if
 # your package does certain things.  But this isn't really a big deal.
 
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
 # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
 # AM_INIT_AUTOMAKE([OPTIONS])
 # -----------------------------------------------
@@ -650,7 +650,7 @@ AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
 # arguments mandatory, and then we can depend on a new Autoconf
 # release and drop the old call support.
 AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.62])dnl
+[AC_PREREQ([2.65])dnl
 dnl Autoconf wants to disallow AM_ names.  We explicitly allow
 dnl the ones we care about.
 m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
@@ -680,8 +680,7 @@ AC_SUBST([CYGPATH_W])
 dnl Distinguish between old-style and new-style calls.
 m4_ifval([$2],
 [AC_DIAGNOSE([obsolete],
-[$0: two- and three-arguments forms are deprecated.  For more info, see:
-http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_INIT_AUTOMAKE-invocation])
+             [$0: two- and three-arguments forms are deprecated.])
 m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
  AC_SUBST([PACKAGE], [$1])dnl
  AC_SUBST([VERSION], [$2])],
@@ -714,8 +713,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
-# We need awk for the "check" target.  The system "awk" is bad on
-# some platforms.
+# We need awk for the "check" target (and possibly the TAP driver).  The
+# system "awk" is bad on some platforms.
 AC_REQUIRE([AC_PROG_AWK])dnl
 AC_REQUIRE([AC_PROG_MAKE_SET])dnl
 AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@@ -735,21 +734,63 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJC],
 		  [_AM_DEPENDENCIES([OBJC])],
 		  [m4_define([AC_PROG_OBJC],
 			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
-dnl Support for Objective C++ was only introduced in Autoconf 2.65,
-dnl but we still cater to Autoconf 2.62.
-m4_ifdef([AC_PROG_OBJCXX],
-[AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
 		  [_AM_DEPENDENCIES([OBJCXX])],
 		  [m4_define([AC_PROG_OBJCXX],
-			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl
+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
 ])
-_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
-dnl The 'parallel-tests' driver may need to know about EXEEXT, so add the
-dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This macro
-dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
 AC_CONFIG_COMMANDS_PRE(dnl
 [m4_provide_if([_AM_COMPILER_EXEEXT],
   [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake at gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+  fi
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
 ])
 
 dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
@@ -758,7 +799,6 @@ dnl mangled by Autoconf and run in a shell conditional statement.
 m4_define([_AC_COMPILER_EXEEXT],
 m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
 
-
 # When config.status generates a header, we must update the stamp-h file.
 # This file resides in the same directory as the config header
 # that is generated.  The stamp files are numbered to have different names.
@@ -780,20 +820,18 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 8
-
 # AM_PROG_INSTALL_SH
 # ------------------
 # Define $install_sh.
 AC_DEFUN([AM_PROG_INSTALL_SH],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
   case $am_aux_dir in
   *\ * | *\	*)
     install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -803,14 +841,12 @@ if test x"${install_sh}" != xset; then
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2012 Free Software Foundation, Inc.
+# Copyright (C) 2003-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 2
-
 # Check whether the underlying file-system supports filenames
 # with a leading dot.  For instance MS-DOS doesn't.
 AC_DEFUN([AM_SET_LEADING_DOT],
@@ -827,14 +863,12 @@ AC_SUBST([am__leading_dot])])
 # Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
 # From Jim Meyering
 
-# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 7
-
 # AM_MAINTAINER_MODE([DEFAULT-MODE])
 # ----------------------------------
 # Control maintainer-specific portions of Makefiles.
@@ -862,18 +896,14 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
 ]
 )
 
-AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
-
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 5
-
 # AM_MAKE_INCLUDE()
 # -----------------
 # Check to see how make treats includes.
@@ -918,14 +948,12 @@ rm -f confinc confmf
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2012 Free Software Foundation, Inc.
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 7
-
 # AM_MISSING_PROG(NAME, PROGRAM)
 # ------------------------------
 AC_DEFUN([AM_MISSING_PROG],
@@ -933,11 +961,10 @@ AC_DEFUN([AM_MISSING_PROG],
 $1=${$1-"${am_missing_run}$2"}
 AC_SUBST($1)])
 
-
 # AM_MISSING_HAS_RUN
 # ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
 AC_DEFUN([AM_MISSING_HAS_RUN],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
 AC_REQUIRE_AUX_FILE([missing])dnl
@@ -950,24 +977,51 @@ if test x"${MISSING+set}" != xset; then
   esac
 fi
 # Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
-  am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
 else
   am_missing_run=
   AC_MSG_WARN(['missing' script is too old or missing])
 fi
 ])
 
+#  -*- Autoconf -*-
+# Obsolete and "removed" macros, that must however still report explicit
+# error messages when used, to smooth transition.
+#
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([AM_CONFIG_HEADER],
+[AC_DIAGNOSE([obsolete],
+['$0': this macro is obsolete.
+You should use the 'AC][_CONFIG_HEADERS' macro instead.])dnl
+AC_CONFIG_HEADERS($@)])
+
+AC_DEFUN([AM_PROG_CC_STDC],
+[AC_PROG_CC
+am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc
+AC_DIAGNOSE([obsolete],
+['$0': this macro is obsolete.
+You should simply use the 'AC][_PROG_CC' macro instead.
+Also, your code should no longer depend upon 'am_cv_prog_cc_stdc',
+but upon 'ac_cv_prog_cc_stdc'.])])
+
+AC_DEFUN([AM_C_PROTOTYPES],
+         [AC_FATAL([automatic de-ANSI-fication support has been removed])])
+AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES])
+
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 6
-
 # _AM_MANGLE_OPTION(NAME)
 # -----------------------
 AC_DEFUN([_AM_MANGLE_OPTION],
@@ -991,15 +1045,77 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+  [whether $CC understands -c and -o together],
+  [am_cv_prog_cc_c_o],
+  [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 9
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+   ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
 # AM_SANITY_CHECK
 # ---------------
@@ -1076,13 +1192,71 @@ AC_CONFIG_COMMANDS_PRE(
 rm -f conftest.file
 ])
 
-# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+# Copyright (C) 2009-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 2
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
 # AM_PROG_INSTALL_STRIP
 # ---------------------
@@ -1106,14 +1280,12 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2012 Free Software Foundation, Inc.
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 3
-
 # _AM_SUBST_NOTMAKE(VARIABLE)
 # ---------------------------
 # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
@@ -1127,14 +1299,12 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2012 Free Software Foundation, Inc.
+# Copyright (C) 2004-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 3
-
 # _AM_PROG_TAR(FORMAT)
 # --------------------
 # Check how to create a tarball in format FORMAT.
@@ -1148,76 +1318,114 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 # Substitute a variable $(am__untar) that extract such
 # a tarball read from stdin.
 #     $(am__untar) < result.tar
+#
 AC_DEFUN([_AM_PROG_TAR],
 [# Always define AMTAR for backward compatibility.  Yes, it's still used
 # in the wild :-(  We should find a proper way to deprecate it ...
 AC_SUBST([AMTAR], ['$${TAR-tar}'])
-m4_if([$1], [v7],
-     [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
-     [m4_case([$1], [ustar],, [pax],,
-              [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
+
+# We'll loop over all known methods to create a tar archive until one works.
 _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of '-'.
-for _am_tool in $_am_tools
-do
-  case $_am_tool in
-  gnutar)
-    for _am_tar in tar gnutar gtar;
-    do
-      AM_RUN_LOG([$_am_tar --version]) && break
-    done
-    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
-    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
-    am__untar="$_am_tar -xf -"
-    ;;
-  plaintar)
-    # Must skip GNU tar: if it does not support --format= it doesn't create
-    # ustar tarball either.
-    (tar --version) >/dev/null 2>&1 && continue
-    am__tar='tar chf - "$$tardir"'
-    am__tar_='tar chf - "$tardir"'
-    am__untar='tar xf -'
-    ;;
-  pax)
-    am__tar='pax -L -x $1 -w "$$tardir"'
-    am__tar_='pax -L -x $1 -w "$tardir"'
-    am__untar='pax -r'
-    ;;
-  cpio)
-    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
-    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
-    am__untar='cpio -i -H $1 -d'
-    ;;
-  none)
-    am__tar=false
-    am__tar_=false
-    am__untar=false
-    ;;
-  esac
 
-  # If the value was cached, stop now.  We just wanted to have am__tar
-  # and am__untar set.
-  test -n "${am_cv_prog_tar_$1}" && break
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  for _am_tool in $_am_tools; do
+    case $_am_tool in
+    gnutar)
+      for _am_tar in tar gnutar gtar; do
+        AM_RUN_LOG([$_am_tar --version]) && break
+      done
+      am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+      am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+      am__untar="$_am_tar -xf -"
+      ;;
+    plaintar)
+      # Must skip GNU tar: if it does not support --format= it doesn't create
+      # ustar tarball either.
+      (tar --version) >/dev/null 2>&1 && continue
+      am__tar='tar chf - "$$tardir"'
+      am__tar_='tar chf - "$tardir"'
+      am__untar='tar xf -'
+      ;;
+    pax)
+      am__tar='pax -L -x $1 -w "$$tardir"'
+      am__tar_='pax -L -x $1 -w "$tardir"'
+      am__untar='pax -r'
+      ;;
+    cpio)
+      am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+      am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+      am__untar='cpio -i -H $1 -d'
+      ;;
+    none)
+      am__tar=false
+      am__tar_=false
+      am__untar=false
+      ;;
+    esac
 
-  # tar/untar a dummy directory, and stop if the command works
-  rm -rf conftest.dir
-  mkdir conftest.dir
-  echo GrepMe > conftest.dir/file
-  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+    # If the value was cached, stop now.  We just wanted to have am__tar
+    # and am__untar set.
+    test -n "${am_cv_prog_tar_$1}" && break
+
+    # tar/untar a dummy directory, and stop if the command works.
+    rm -rf conftest.dir
+    mkdir conftest.dir
+    echo GrepMe > conftest.dir/file
+    AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+    rm -rf conftest.dir
+    if test -s conftest.tar; then
+      AM_RUN_LOG([$am__untar <conftest.tar])
+      AM_RUN_LOG([cat conftest.dir/file])
+      grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+    fi
+  done
   rm -rf conftest.dir
-  if test -s conftest.tar; then
-    AM_RUN_LOG([$am__untar <conftest.tar])
-    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
-  fi
-done
-rm -rf conftest.dir
 
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+  AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+  AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
 AC_SUBST([am__tar])
 AC_SUBST([am__untar])
 ]) # _AM_PROG_TAR
diff --git a/compile b/compile
new file mode 100755
index 0000000..531136b
--- /dev/null
+++ b/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey at cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""	$nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv/,$2, in
+	*,$file_conv,*)
+	  ;;
+	mingw/*)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin/*)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine/*)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+    if test -f "$dir/lib$lib.a"; then
+      found=yes
+      lib=$dir/lib$lib.a
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+	-o)
+	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
+	  eat=1
+	  case $2 in
+	    *.o | *.[oO][bB][jJ])
+	      func_file_conv "$2"
+	      set x "$@" -Fo"$file"
+	      shift
+	      ;;
+	    *)
+	      func_file_conv "$2"
+	      set x "$@" -Fe"$file"
+	      shift
+	      ;;
+	  esac
+	  ;;
+	-I)
+	  eat=1
+	  func_file_conv "$2" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-I*)
+	  func_file_conv "${1#-I}" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-l)
+	  eat=1
+	  func_cl_dashl "$2"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-l*)
+	  func_cl_dashl "${1#-l}"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-L)
+	  eat=1
+	  func_cl_dashL "$2"
+	  ;;
+	-L*)
+	  func_cl_dashL "${1#-L}"
+	  ;;
+	-static)
+	  shared=false
+	  ;;
+	-Wl,*)
+	  arg=${1#-Wl,}
+	  save_ifs="$IFS"; IFS=','
+	  for flag in $arg; do
+	    IFS="$save_ifs"
+	    linker_opts="$linker_opts $flag"
+	  done
+	  IFS="$save_ifs"
+	  ;;
+	-Xlinker)
+	  eat=1
+	  linker_opts="$linker_opts $2"
+	  ;;
+	-*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+	  func_file_conv "$1"
+	  set x "$@" -Tp"$file"
+	  shift
+	  ;;
+	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+	  func_file_conv "$1" mingw
+	  set x "$@" "$file"
+	  shift
+	  ;;
+	*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
+case $1 in
+  '')
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as 'compile cc -o foo foo.c'.
+	# So we strip '-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no '-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # '.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/config.h.in b/config.h.in
index 651fdf6..0b77022 100644
--- a/config.h.in
+++ b/config.h.in
@@ -3,6 +3,9 @@
 /* Should be defined in order to enable LIBXML2 support. */
 #undef ENABLE_LIBXML2
 
+/* Define to 1 if you have the <CharLS/interface.h> header file. */
+#undef HAVE_CHARLS_INTERFACE_H
+
 /* depending on SQLite library version. */
 #undef HAVE_DECL_SQLITE_DBSTATUS_CACHE_HIT
 
@@ -60,8 +63,11 @@
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
-/* Define to 1 if you have the `gaiagraphics' library (-lgaiagraphics). */
-#undef HAVE_LIBGAIAGRAPHICS
+/* Define to 1 if you have the `CharLS' library (-lCharLS). */
+#undef HAVE_LIBCHARLS
+
+/* Define to 1 if you have the `openjp2' library (-lopenjp2). */
+#undef HAVE_LIBOPENJP2
 
 /* Define to 1 if you have the `proj' library (-lproj). */
 #undef HAVE_LIBPROJ
@@ -85,6 +91,12 @@
 /* Define to 1 if you have the `memset' function. */
 #undef HAVE_MEMSET
 
+/* Define to 1 if you have the <openjpeg-2.0/openjpeg.h> header file. */
+#undef HAVE_OPENJPEG_2_0_OPENJPEG_H
+
+/* Define to 1 if you have the <openjpeg-2.1/openjpeg.h> header file. */
+#undef HAVE_OPENJPEG_2_1_OPENJPEG_H
+
 /* Define to 1 if you have the `sqrt' function. */
 #undef HAVE_SQRT
 
@@ -145,9 +157,24 @@
    */
 #undef LT_OBJDIR
 
+/* Should be defined in order to disable CharLS support. */
+#undef OMIT_CHARLS
+
 /* Should be defined in order to disable FREEXL support. */
 #undef OMIT_FREEXL
 
+/* Should be defined in order to disable OpenJpeg support. */
+#undef OMIT_OPENJPEG
+
+/* Should be defined in order to disable RasterLite2 extended support. */
+#undef OMIT_RL2EXTRA
+
+/* Should be defined in order to disable WebP support. */
+#undef OMIT_WEBP
+
+/* testing for OpenJpeg 2.1 */
+#undef OPENJPEG_2_1
+
 /* Name of package */
 #undef PACKAGE
 
diff --git a/configure b/configure
index 0a072ed..3857f8c 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for spatialite_gui 1.7.1.
+# Generated by GNU Autoconf 2.69 for spatialite_gui 2.0.0-devel.
 #
 # Report bugs to <a.furieri at lqt.it>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='spatialite_gui'
 PACKAGE_TARNAME='spatialite_gui'
-PACKAGE_VERSION='1.7.1'
-PACKAGE_STRING='spatialite_gui 1.7.1'
+PACKAGE_VERSION='2.0.0-devel'
+PACKAGE_STRING='spatialite_gui 2.0.0-devel'
 PACKAGE_BUGREPORT='a.furieri at lqt.it'
 PACKAGE_URL=''
 
@@ -635,14 +635,18 @@ ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
 OMIT_SQLITE_STMTSTATUS_AUTOINDEX_FLAGS
+LIBRASTERLITE2_LIBS
+LIBRASTERLITE2_CFLAGS
 LIBSPATIALITE_LIBS
 LIBSPATIALITE_CFLAGS
+LIBLZMA_LIBS
+LIBLZMA_CFLAGS
+LIBWEBP_LIBS
+LIBWEBP_CFLAGS
 LIBXML2_LIBS
 LIBXML2_CFLAGS
 LIBFREEXL_LIBS
 LIBFREEXL_CFLAGS
-LIBGAIAGRAPHICS_LIBS
-LIBGAIAGRAPHICS_CFLAGS
 PKG_CONFIG_LIBDIR
 PKG_CONFIG_PATH
 PKG_CONFIG
@@ -651,7 +655,7 @@ GEOS_LDFLAGS
 GEOSCONFIG
 LIBOBJS
 WX_LIBS
-WX_CONFIG
+WXCONFIG
 CXXCPP
 OTOOL64
 OTOOL
@@ -710,6 +714,10 @@ CXX
 MAINT
 MAINTAINER_MODE_FALSE
 MAINTAINER_MODE_TRUE
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
 am__untar
 am__tar
 AMTAR
@@ -774,6 +782,7 @@ SHELL'
 ac_subst_files=''
 ac_user_opts='
 enable_option_checking
+enable_silent_rules
 enable_maintainer_mode
 enable_dependency_tracking
 enable_shared
@@ -783,9 +792,14 @@ enable_fast_install
 with_gnu_ld
 with_sysroot
 enable_libtool_lock
+with_wxconfig
 with_geosconfig
 enable_freexl
 enable_libxml2
+enable_openjpeg
+enable_webp
+enable_charls
+enable_rl2extra
 enable_sqlite_stmtstatus_autoindex
 '
       ac_precious_vars='build_alias
@@ -804,14 +818,18 @@ CXXCPP
 PKG_CONFIG
 PKG_CONFIG_PATH
 PKG_CONFIG_LIBDIR
-LIBGAIAGRAPHICS_CFLAGS
-LIBGAIAGRAPHICS_LIBS
 LIBFREEXL_CFLAGS
 LIBFREEXL_LIBS
 LIBXML2_CFLAGS
 LIBXML2_LIBS
+LIBWEBP_CFLAGS
+LIBWEBP_LIBS
+LIBLZMA_CFLAGS
+LIBLZMA_LIBS
 LIBSPATIALITE_CFLAGS
-LIBSPATIALITE_LIBS'
+LIBSPATIALITE_LIBS
+LIBRASTERLITE2_CFLAGS
+LIBRASTERLITE2_LIBS'
 
 
 # Initialize some variables set by options.
@@ -1352,7 +1370,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures spatialite_gui 1.7.1 to adapt to many kinds of systems.
+\`configure' configures spatialite_gui 2.0.0-devel to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1422,7 +1440,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of spatialite_gui 1.7.1:";;
+     short | recursive ) echo "Configuration of spatialite_gui 2.0.0-devel:";;
    esac
   cat <<\_ACEOF
 
@@ -1430,6 +1448,8 @@ Optional Features:
   --disable-option-checking  ignore unrecognized --enable/--with options
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
   --enable-maintainer-mode
                           enable make rules and dependencies not useful (and
                           sometimes confusing) to the casual installer
@@ -1444,6 +1464,10 @@ Optional Features:
   --disable-libtool-lock  avoid locking (might break parallel builds)
   --enable-freexl         enables FreeXL inclusion [default=yes]
   --enable-libxml2        enables libxml2 inclusion [default=yes]
+  --enable-openjpeg       enables OpenJpeg inclusion [default=yes]
+  --enable-webp           enables WebP inclusion [default=yes]
+  --enable-charls         enables CharLS inclusion [default=yes]
+  --enable-rl2extra       enables RasterLite2 extended support [default=yes]
   --enable-sqlite_stmtstatus_autoindex
                           enables SQLITE_STMTSTATUS_AUTOINDEX [default=yes]
 
@@ -1455,6 +1479,7 @@ Optional Packages:
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
   --with-sysroot=DIR Search for dependent libraries within DIR
                         (or the compiler's sysroot if not specified).
+  --with-wxconfig=FILE    specify an alternative wx-config file
   --with-geosconfig=FILE  specify an alternative geos-config file
 
 Some influential environment variables:
@@ -1474,10 +1499,6 @@ Some influential environment variables:
               directories to add to pkg-config's search path
   PKG_CONFIG_LIBDIR
               path overriding pkg-config's built-in search path
-  LIBGAIAGRAPHICS_CFLAGS
-              C compiler flags for LIBGAIAGRAPHICS, overriding pkg-config
-  LIBGAIAGRAPHICS_LIBS
-              linker flags for LIBGAIAGRAPHICS, overriding pkg-config
   LIBFREEXL_CFLAGS
               C compiler flags for LIBFREEXL, overriding pkg-config
   LIBFREEXL_LIBS
@@ -1486,10 +1507,22 @@ Some influential environment variables:
               C compiler flags for LIBXML2, overriding pkg-config
   LIBXML2_LIBS
               linker flags for LIBXML2, overriding pkg-config
+  LIBWEBP_CFLAGS
+              C compiler flags for LIBWEBP, overriding pkg-config
+  LIBWEBP_LIBS
+              linker flags for LIBWEBP, overriding pkg-config
+  LIBLZMA_CFLAGS
+              C compiler flags for LIBLZMA, overriding pkg-config
+  LIBLZMA_LIBS
+              linker flags for LIBLZMA, overriding pkg-config
   LIBSPATIALITE_CFLAGS
               C compiler flags for LIBSPATIALITE, overriding pkg-config
   LIBSPATIALITE_LIBS
               linker flags for LIBSPATIALITE, overriding pkg-config
+  LIBRASTERLITE2_CFLAGS
+              C compiler flags for LIBRASTERLITE2, overriding pkg-config
+  LIBRASTERLITE2_LIBS
+              linker flags for LIBRASTERLITE2, overriding pkg-config
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -1557,7 +1590,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-spatialite_gui configure 1.7.1
+spatialite_gui configure 2.0.0-devel
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2147,7 +2180,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by spatialite_gui $as_me 1.7.1, which was
+It was created by spatialite_gui $as_me 2.0.0-devel, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2503,7 +2536,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
-am__api_version='1.12'
+am__api_version='1.15'
 
 ac_aux_dir=
 for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
@@ -2704,8 +2737,8 @@ test "$program_suffix" != NONE &&
 ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
 program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
 
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 if test x"${MISSING+set}" != xset; then
   case $am_aux_dir in
@@ -2716,15 +2749,15 @@ if test x"${MISSING+set}" != xset; then
   esac
 fi
 # Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
-  am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
 else
   am_missing_run=
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
 fi
 
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
   case $am_aux_dir in
   *\ * | *\	*)
     install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -2957,6 +2990,45 @@ else
 fi
 rmdir .tst 2>/dev/null
 
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
 if test "`cd $srcdir && pwd`" != "`pwd`"; then
   # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
   # is not polluted with repeated "-I."
@@ -2979,7 +3051,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='spatialite_gui'
- VERSION='1.7.1'
+ VERSION='2.0.0-devel'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3013,12 +3085,16 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 mkdir_p='$(MKDIR_P)'
 
-# We need awk for the "check" target.  The system "awk" is bad on
-# some platforms.
+# We need awk for the "check" target (and possibly the TAP driver).  The
+# system "awk" is bad on some platforms.
 # Always define AMTAR for backward compatibility.  Yes, it's still used
 # in the wild :-(  We should find a proper way to deprecate it ...
 AMTAR='$${TAR-tar}'
 
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
 am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
 
 
@@ -3026,6 +3102,49 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
 
 
 
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake at gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+  fi
+fi
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
     # Check whether --enable-maintainer-mode was given.
@@ -3066,6 +3185,11 @@ ac_config_headers="$ac_config_headers config.h"
 
 
 
+
+
+
+
+
 # Checks for programs.
 ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
@@ -4304,6 +4428,65 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
 depcc="$CC"   am_compiler_list=
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
@@ -15497,16 +15680,26 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
-# Extract the first word of "wx-config", so it can be a program name with args.
+
+# Check whether --with-wxconfig was given.
+if test "${with_wxconfig+set}" = set; then :
+  withval=$with_wxconfig; WXCONFIG="$withval"
+else
+  WXCONFIG=""
+fi
+
+if test "x$WXCONFIG" = "x"; then
+      # WXCONFIG was not specified, so search within the current path
+      # Extract the first word of "wx-config", so it can be a program name with args.
 set dummy wx-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_WX_CONFIG+:} false; then :
+if ${ac_cv_path_WXCONFIG+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  case $WX_CONFIG in
+  case $WXCONFIG in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_WX_CONFIG="$WX_CONFIG" # Let the user override the test with a path.
+  ac_cv_path_WXCONFIG="$WXCONFIG" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -15516,7 +15709,7 @@ do
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
   if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_WX_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_WXCONFIG="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -15524,26 +15717,39 @@ done
   done
 IFS=$as_save_IFS
 
-  test -z "$ac_cv_path_WX_CONFIG" && ac_cv_path_WX_CONFIG="not_found"
   ;;
 esac
 fi
-WX_CONFIG=$ac_cv_path_WX_CONFIG
-if test -n "$WX_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WX_CONFIG" >&5
-$as_echo "$WX_CONFIG" >&6; }
+WXCONFIG=$ac_cv_path_WXCONFIG
+if test -n "$WXCONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WXCONFIG" >&5
+$as_echo "$WXCONFIG" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
 
-if test x$WX_CONFIG == xnot_found; then
-  as_fn_error $? "cannot find wx-config (WxWidgets configuration helper), bailing out - try installing WxWidgets GTK development packages" "$LINENO" 5
+      # If we couldn't find wx-config, display an error
+      if test "x$WXCONFIG" = "x"; then
+              as_fn_error $? "could not find wx-config within the current path. You may need to try re-running configure with a --with-wxconfig parameter." "$LINENO" 5
+      fi
+else
+      # WXCONFIG was specified; display a message to the user
+      if test "x$WXCONFIG" = "xyes"; then
+              as_fn_error $? "you must specify a parameter to --with-wxconfig, e.g. --with-wxconfig=/path/to/wx-config" "$LINENO" 5
+      else
+              if test -f $WXCONFIG; then
+                      { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using user-specified wx-config file: $WXCONFIG" >&5
+$as_echo "Using user-specified wx-config file: $WXCONFIG" >&6; }
+              else
+                      as_fn_error $? "the user-specified wx-config file $WXCONFIG does not exist" "$LINENO" 5
+              fi
+      fi
 fi
-CXXFLAGS="$(wx-config --cxxflags)"
-AM_CXXFLAGS="$(wx-config --cxxflags)"
-WX_LIBS="$(wx-config --libs)"
+CXXFLAGS=`$WXCONFIG --cxxflags`
+AM_CXXFLAGS=`$WXCONFIG --cxxflags`
+WX_LIBS=`$WXCONFIG --libs std,aui`
 
 
 # Checks for header files.
@@ -16477,6 +16683,17 @@ fi
 LIBS="$LIBS_SAVE"
 LIBS=$LIBS$GEOS_LDFLAGS' -lgeos_c'
 
+#-----------------------------------------------------------------------
+#   --enable-freexl
+#
+# Check whether --enable-freexl was given.
+if test "${enable_freexl+set}" = set; then :
+  enableval=$enable_freexl;
+else
+  enable_freexl=yes
+fi
+
+if test x"$enable_freexl" != "xno"; then
 
 
 
@@ -16599,19 +16816,108 @@ $as_echo "no" >&6; }
 fi
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBGAIAGRAPHICS" >&5
-$as_echo_n "checking for LIBGAIAGRAPHICS... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBFREEXL" >&5
+$as_echo_n "checking for LIBFREEXL... " >&6; }
+
+if test -n "$LIBFREEXL_CFLAGS"; then
+    pkg_cv_LIBFREEXL_CFLAGS="$LIBFREEXL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"freexl\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "freexl") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBFREEXL_CFLAGS=`$PKG_CONFIG --cflags "freexl" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$LIBFREEXL_LIBS"; then
+    pkg_cv_LIBFREEXL_LIBS="$LIBFREEXL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"freexl\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "freexl") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBFREEXL_LIBS=`$PKG_CONFIG --libs "freexl" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        LIBFREEXL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "freexl" 2>&1`
+        else
+	        LIBFREEXL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "freexl" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$LIBFREEXL_PKG_ERRORS" >&5
+
+	as_fn_error $? "'libfreexl' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	as_fn_error $? "'libfreexl' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+else
+	LIBFREEXL_CFLAGS=$pkg_cv_LIBFREEXL_CFLAGS
+	LIBFREEXL_LIBS=$pkg_cv_LIBFREEXL_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+else
+  $as_echo "#define OMIT_FREEXL 1" >>confdefs.h
+
+fi
+
+#-----------------------------------------------------------------------
+#   --enable-libxml2
+#
+# Check whether --enable-libxml2 was given.
+if test "${enable_libxml2+set}" = set; then :
+  enableval=$enable_libxml2;
+else
+  enable_libxml2=yes
+fi
+
+if test x"$enable_libxml2" != "xno"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBXML2" >&5
+$as_echo_n "checking for LIBXML2... " >&6; }
 
-if test -n "$LIBGAIAGRAPHICS_CFLAGS"; then
-    pkg_cv_LIBGAIAGRAPHICS_CFLAGS="$LIBGAIAGRAPHICS_CFLAGS"
+if test -n "$LIBXML2_CFLAGS"; then
+    pkg_cv_LIBXML2_CFLAGS="$LIBXML2_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gaiagraphics\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "gaiagraphics") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxml-2.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libxml-2.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBGAIAGRAPHICS_CFLAGS=`$PKG_CONFIG --cflags "gaiagraphics" 2>/dev/null`
+  pkg_cv_LIBXML2_CFLAGS=`$PKG_CONFIG --cflags "libxml-2.0" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -16619,16 +16925,16 @@ fi
  else
     pkg_failed=untried
 fi
-if test -n "$LIBGAIAGRAPHICS_LIBS"; then
-    pkg_cv_LIBGAIAGRAPHICS_LIBS="$LIBGAIAGRAPHICS_LIBS"
+if test -n "$LIBXML2_LIBS"; then
+    pkg_cv_LIBXML2_LIBS="$LIBXML2_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gaiagraphics\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "gaiagraphics") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxml-2.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libxml-2.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBGAIAGRAPHICS_LIBS=`$PKG_CONFIG --libs "gaiagraphics" 2>/dev/null`
+  pkg_cv_LIBXML2_LIBS=`$PKG_CONFIG --libs "libxml-2.0" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -16649,35 +16955,83 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        LIBGAIAGRAPHICS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gaiagraphics" 2>&1`
+	        LIBXML2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libxml-2.0" 2>&1`
         else
-	        LIBGAIAGRAPHICS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gaiagraphics" 2>&1`
+	        LIBXML2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libxml-2.0" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$LIBGAIAGRAPHICS_PKG_ERRORS" >&5
+	echo "$LIBXML2_PKG_ERRORS" >&5
 
-	as_fn_error $? "'libgaiagraphics' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+	as_fn_error $? "'libxml2' is required but it doesn't seem to be installed on this system." "$LINENO" 5
 elif test $pkg_failed = untried; then
      	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-	as_fn_error $? "'libgaiagraphics' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+	as_fn_error $? "'libxml2' is required but it doesn't seem to be installed on this system." "$LINENO" 5
 else
-	LIBGAIAGRAPHICS_CFLAGS=$pkg_cv_LIBGAIAGRAPHICS_CFLAGS
-	LIBGAIAGRAPHICS_LIBS=$pkg_cv_LIBGAIAGRAPHICS_LIBS
+	LIBXML2_CFLAGS=$pkg_cv_LIBXML2_CFLAGS
+	LIBXML2_LIBS=$pkg_cv_LIBXML2_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
 fi
 
 
+  $as_echo "#define ENABLE_LIBXML2 1" >>confdefs.h
+
+fi
+
+#-----------------------------------------------------------------------
+#   --enable-openjpeg
+#
+# Check whether --enable-openjpeg was given.
+if test "${enable_openjpeg+set}" = set; then :
+  enableval=$enable_openjpeg;
+else
+  enable_openjpeg=yes
+fi
+
+    if test x"$enable_openjpeg" != "xno"; then
+    #
+    # testing OpenJpeg-2 headers
+    # they could be either on -/include/openjpeg-2.0
+    #                   or on -/include/openjpeg-2.1
+    #
+    for ac_header in openjpeg-2.0/openjpeg.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "openjpeg-2.0/openjpeg.h" "ac_cv_header_openjpeg_2_0_openjpeg_h" "$ac_includes_default"
+if test "x$ac_cv_header_openjpeg_2_0_openjpeg_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_OPENJPEG_2_0_OPENJPEG_H 1
+_ACEOF
+
+fi
+
+done
+
+    for ac_header in openjpeg-2.1/openjpeg.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "openjpeg-2.1/openjpeg.h" "ac_cv_header_openjpeg_2_1_openjpeg_h" "$ac_includes_default"
+if test "x$ac_cv_header_openjpeg_2_1_openjpeg_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_OPENJPEG_2_1_OPENJPEG_H 1
+_ACEOF
+
+fi
+
+done
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gGraphCreateSVG in -lgaiagraphics" >&5
-$as_echo_n "checking for gGraphCreateSVG in -lgaiagraphics... " >&6; }
-if ${ac_cv_lib_gaiagraphics_gGraphCreateSVG+:} false; then :
+    if test x"$ac_cv_header_openjpeg_2_0_openjpeg_h" != x"yes" &&
+        test x"$ac_cv_header_openjpeg_2_1_openjpeg_h" != x"yes";
+    then
+        as_fn_error $? "'OpenJpeg-2' is required but the header (openjpeg.h) doesn't seem to be installed on this system" "$LINENO" 5
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for opj_create_decompress in -lopenjp2" >&5
+$as_echo_n "checking for opj_create_decompress in -lopenjp2... " >&6; }
+if ${ac_cv_lib_openjp2_opj_create_decompress+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lgaiagraphics -lm $LIBS"
+LIBS="-lopenjp2 -lm $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -16687,64 +17041,98 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 #ifdef __cplusplus
 extern "C"
 #endif
-char gGraphCreateSVG ();
+char opj_create_decompress ();
 int
 main ()
 {
-return gGraphCreateSVG ();
+return opj_create_decompress ();
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_gaiagraphics_gGraphCreateSVG=yes
+  ac_cv_lib_openjp2_opj_create_decompress=yes
 else
-  ac_cv_lib_gaiagraphics_gGraphCreateSVG=no
+  ac_cv_lib_openjp2_opj_create_decompress=no
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gaiagraphics_gGraphCreateSVG" >&5
-$as_echo "$ac_cv_lib_gaiagraphics_gGraphCreateSVG" >&6; }
-if test "x$ac_cv_lib_gaiagraphics_gGraphCreateSVG" = xyes; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openjp2_opj_create_decompress" >&5
+$as_echo "$ac_cv_lib_openjp2_opj_create_decompress" >&6; }
+if test "x$ac_cv_lib_openjp2_opj_create_decompress" = xyes; then :
   cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBGAIAGRAPHICS 1
+#define HAVE_LIBOPENJP2 1
+_ACEOF
+
+  LIBS="-lopenjp2 $LIBS"
+
+else
+  as_fn_error $? "'libopenjp2' is required but it doesn't seems to be installed on this system." "$LINENO" 5
+fi
+
+    # testing for OpenJpeg 2.0 or 2.1
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef HAVE_OPENJPEG_2_1_OPENJPEG_H
+                                       #include <openjpeg-2.1/openjpeg.h>
+                                       #else
+                                       #include <openjpeg-2.0/openjpeg.h>
+                                       #endif
+int
+main ()
+{
+void *d; opj_stream_t *s; opj_stream_set_user_data (s, &d, NULL);
+  ;
+  return 0;
+}
 _ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+                      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+                      $as_echo "#define OPENJPEG_2_1 1" >>confdefs.h
 
-  LIBS="-lgaiagraphics $LIBS"
 
 else
-  as_fn_error $? "found an obsolete 'libgaiagraphics': please update to a more recent version." "$LINENO" 5
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  $as_echo "#define OMIT_OPENJPEG 1" >>confdefs.h
 
+fi
+#-----------------------------------------------------------------------
 
 #-----------------------------------------------------------------------
-#   --enable-freexl
+#   --enable-webp
 #
-# Check whether --enable-freexl was given.
-if test "${enable_freexl+set}" = set; then :
-  enableval=$enable_freexl;
+# Check whether --enable-webp was given.
+if test "${enable_webp+set}" = set; then :
+  enableval=$enable_webp;
 else
-  enable_freexl=yes
+  enable_webp=yes
 fi
 
-if test x"$enable_freexl" != "xno"; then
+if test x"$enable_webp" != "xno"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBFREEXL" >&5
-$as_echo_n "checking for LIBFREEXL... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBWEBP" >&5
+$as_echo_n "checking for LIBWEBP... " >&6; }
 
-if test -n "$LIBFREEXL_CFLAGS"; then
-    pkg_cv_LIBFREEXL_CFLAGS="$LIBFREEXL_CFLAGS"
+if test -n "$LIBWEBP_CFLAGS"; then
+    pkg_cv_LIBWEBP_CFLAGS="$LIBWEBP_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"freexl\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "freexl") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libwebp\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libwebp") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBFREEXL_CFLAGS=`$PKG_CONFIG --cflags "freexl" 2>/dev/null`
+  pkg_cv_LIBWEBP_CFLAGS=`$PKG_CONFIG --cflags "libwebp" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -16752,16 +17140,16 @@ fi
  else
     pkg_failed=untried
 fi
-if test -n "$LIBFREEXL_LIBS"; then
-    pkg_cv_LIBFREEXL_LIBS="$LIBFREEXL_LIBS"
+if test -n "$LIBWEBP_LIBS"; then
+    pkg_cv_LIBWEBP_LIBS="$LIBWEBP_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"freexl\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "freexl") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libwebp\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libwebp") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBFREEXL_LIBS=`$PKG_CONFIG --libs "freexl" 2>/dev/null`
+  pkg_cv_LIBWEBP_LIBS=`$PKG_CONFIG --libs "libwebp" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -16782,21 +17170,21 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        LIBFREEXL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "freexl" 2>&1`
+	        LIBWEBP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libwebp" 2>&1`
         else
-	        LIBFREEXL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "freexl" 2>&1`
+	        LIBWEBP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libwebp" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$LIBFREEXL_PKG_ERRORS" >&5
+	echo "$LIBWEBP_PKG_ERRORS" >&5
 
-	as_fn_error $? "'libfreexl' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+	as_fn_error $? "'libwebp' is required but it doesn't seems to be installed on this system." "$LINENO" 5
 elif test $pkg_failed = untried; then
      	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-	as_fn_error $? "'libfreexl' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+	as_fn_error $? "'libwebp' is required but it doesn't seems to be installed on this system." "$LINENO" 5
 else
-	LIBFREEXL_CFLAGS=$pkg_cv_LIBFREEXL_CFLAGS
-	LIBFREEXL_LIBS=$pkg_cv_LIBFREEXL_LIBS
+	LIBWEBP_CFLAGS=$pkg_cv_LIBWEBP_CFLAGS
+	LIBWEBP_LIBS=$pkg_cv_LIBWEBP_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
@@ -16804,36 +17192,104 @@ fi
 
 
 else
-  $as_echo "#define OMIT_FREEXL 1" >>confdefs.h
+  $as_echo "#define OMIT_WEBP 1" >>confdefs.h
 
 fi
+#-----------------------------------------------------------------------
 
 #-----------------------------------------------------------------------
-#   --enable-libxml2
+#   --enable-charls
 #
-# Check whether --enable-libxml2 was given.
-if test "${enable_libxml2+set}" = set; then :
-  enableval=$enable_libxml2;
+# Check whether --enable-charls was given.
+if test "${enable_charls+set}" = set; then :
+  enableval=$enable_charls;
 else
-  enable_libxml2=yes
+  enable_charls=yes
 fi
 
-if test x"$enable_libxml2" != "xno"; then
+if test x"$enable_charls" != "xno"; then
+    for ac_header in CharLS/interface.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "CharLS/interface.h" "ac_cv_header_CharLS_interface_h" "$ac_includes_default"
+if test "x$ac_cv_header_CharLS_interface_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CHARLS_INTERFACE_H 1
+_ACEOF
+
+else
+  as_fn_error $? "cannot find CharLS/interface.h, bailing out" "$LINENO" 5
+fi
+
+done
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JpegLsEncode in -lCharLS" >&5
+$as_echo_n "checking for JpegLsEncode in -lCharLS... " >&6; }
+if ${ac_cv_lib_CharLS_JpegLsEncode+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lCharLS -lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char JpegLsEncode ();
+int
+main ()
+{
+return JpegLsEncode ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_CharLS_JpegLsEncode=yes
+else
+  ac_cv_lib_CharLS_JpegLsEncode=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_CharLS_JpegLsEncode" >&5
+$as_echo "$ac_cv_lib_CharLS_JpegLsEncode" >&6; }
+if test "x$ac_cv_lib_CharLS_JpegLsEncode" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCHARLS 1
+_ACEOF
+
+  LIBS="-lCharLS $LIBS"
+
+else
+  as_fn_error $? "'libCharLS' is required but it doesn't seems to be installed on this system." "$LINENO" 5
+fi
+
+else
+  $as_echo "#define OMIT_CHARLS 1" >>confdefs.h
+
+fi
+#-----------------------------------------------------------------------
+
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBXML2" >&5
-$as_echo_n "checking for LIBXML2... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBLZMA" >&5
+$as_echo_n "checking for LIBLZMA... " >&6; }
 
-if test -n "$LIBXML2_CFLAGS"; then
-    pkg_cv_LIBXML2_CFLAGS="$LIBXML2_CFLAGS"
+if test -n "$LIBLZMA_CFLAGS"; then
+    pkg_cv_LIBLZMA_CFLAGS="$LIBLZMA_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxml-2.0\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libxml-2.0") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblzma\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "liblzma") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBXML2_CFLAGS=`$PKG_CONFIG --cflags "libxml-2.0" 2>/dev/null`
+  pkg_cv_LIBLZMA_CFLAGS=`$PKG_CONFIG --cflags "liblzma" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -16841,16 +17297,16 @@ fi
  else
     pkg_failed=untried
 fi
-if test -n "$LIBXML2_LIBS"; then
-    pkg_cv_LIBXML2_LIBS="$LIBXML2_LIBS"
+if test -n "$LIBLZMA_LIBS"; then
+    pkg_cv_LIBLZMA_LIBS="$LIBLZMA_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxml-2.0\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libxml-2.0") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblzma\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "liblzma") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBXML2_LIBS=`$PKG_CONFIG --libs "libxml-2.0" 2>/dev/null`
+  pkg_cv_LIBLZMA_LIBS=`$PKG_CONFIG --libs "liblzma" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -16871,30 +17327,27 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        LIBXML2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libxml-2.0" 2>&1`
+	        LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblzma" 2>&1`
         else
-	        LIBXML2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libxml-2.0" 2>&1`
+	        LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblzma" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$LIBXML2_PKG_ERRORS" >&5
+	echo "$LIBLZMA_PKG_ERRORS" >&5
 
-	as_fn_error $? "'libxml2' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+	as_fn_error $? "'liblzma' is required but it doesn't seems to be installed on this system." "$LINENO" 5
 elif test $pkg_failed = untried; then
      	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-	as_fn_error $? "'libxml2' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+	as_fn_error $? "'liblzma' is required but it doesn't seems to be installed on this system." "$LINENO" 5
 else
-	LIBXML2_CFLAGS=$pkg_cv_LIBXML2_CFLAGS
-	LIBXML2_LIBS=$pkg_cv_LIBXML2_LIBS
+	LIBLZMA_CFLAGS=$pkg_cv_LIBLZMA_CFLAGS
+	LIBLZMA_LIBS=$pkg_cv_LIBLZMA_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
 fi
 
 
-  $as_echo "#define ENABLE_LIBXML2 1" >>confdefs.h
-
-fi
 
 
 pkg_failed=no
@@ -16975,6 +17428,96 @@ if test "x$(pkg-config --cflags spatialite|grep "DSPATIALITE_AMALGAMATION=1")" !
 fi
 
 
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBRASTERLITE2" >&5
+$as_echo_n "checking for LIBRASTERLITE2... " >&6; }
+
+if test -n "$LIBRASTERLITE2_CFLAGS"; then
+    pkg_cv_LIBRASTERLITE2_CFLAGS="$LIBRASTERLITE2_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"rasterlite2\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "rasterlite2") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBRASTERLITE2_CFLAGS=`$PKG_CONFIG --cflags "rasterlite2" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$LIBRASTERLITE2_LIBS"; then
+    pkg_cv_LIBRASTERLITE2_LIBS="$LIBRASTERLITE2_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"rasterlite2\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "rasterlite2") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBRASTERLITE2_LIBS=`$PKG_CONFIG --libs "rasterlite2" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        LIBRASTERLITE2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "rasterlite2" 2>&1`
+        else
+	        LIBRASTERLITE2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "rasterlite2" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$LIBRASTERLITE2_PKG_ERRORS" >&5
+
+	as_fn_error $? "'librasterlite2' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	as_fn_error $? "'librasterlite2' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+else
+	LIBRASTERLITE2_CFLAGS=$pkg_cv_LIBRASTERLITE2_CFLAGS
+	LIBRASTERLITE2_LIBS=$pkg_cv_LIBRASTERLITE2_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+
+#-----------------------------------------------------------------------
+#   --enable-rl2extra
+#
+# Check whether --enable-rl2extra was given.
+if test "${enable_rl2extra+set}" = set; then :
+  enableval=$enable_rl2extra;
+else
+  enable_rl2extra=yes
+fi
+
+if test x"$enable_rl2extra" != "xyes"; then
+  $as_echo "#define OMIT_RL2EXTRA 1" >>confdefs.h
+
+fi
+#-----------------------------------------------------------------------
+
 ac_config_files="$ac_config_files Makefile icons/Makefile win_resource/Makefile gnome_resource/Makefile mac_resource/Makefile"
 
 
@@ -17161,7 +17704,6 @@ DEFS=-DHAVE_CONFIG_H
 
 ac_libobjs=
 ac_ltlibobjs=
-U=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
@@ -17605,7 +18147,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by spatialite_gui $as_me 1.7.1, which was
+This file was extended by spatialite_gui $as_me 2.0.0-devel, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -17671,7 +18213,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-spatialite_gui config.status 1.7.1
+spatialite_gui config.status 2.0.0-devel
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -18783,7 +19325,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
 
   case $ac_file$ac_mode in
     "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
-  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
   case $CONFIG_FILES in
@@ -18834,7 +19376,7 @@ $as_echo X"$mf" |
     DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
     test -z "$DEPDIR" && continue
     am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "am__include" && continue
+    test -z "$am__include" && continue
     am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
     # Find all dependency output files, they are included files with
     # $(DEPDIR) in their names.  We invoke sed twice because it is the
diff --git a/configure.ac b/configure.ac
index 80ec4a8..2d0da56 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.61)
-AC_INIT(spatialite_gui, 1.7.1, a.furieri at lqt.it)
+AC_INIT(spatialite_gui, 2.0.0-devel, a.furieri at lqt.it)
 AC_LANG(C)
 AC_CONFIG_MACRO_DIR([m4])
 
@@ -17,6 +17,16 @@ AH_TEMPLATE([OMIT_FREEXL],
             [Should be defined in order to disable FREEXL support.])
 AH_TEMPLATE([ENABLE_LIBXML2],
             [Should be defined in order to enable LIBXML2 support.])
+AH_TEMPLATE([OMIT_WEBP],
+            [Should be defined in order to disable WebP support.])
+AH_TEMPLATE([OPENJPEG_2_1],
+            [testing for OpenJpeg 2.1])
+AH_TEMPLATE([OMIT_OPENJPEG],
+            [Should be defined in order to disable OpenJpeg support.])
+AH_TEMPLATE([OMIT_CHARLS],
+            [Should be defined in order to disable CharLS support.])
+AH_TEMPLATE([OMIT_RL2EXTRA],
+            [Should be defined in order to disable RasterLite2 extended support.])
 AH_TEMPLATE([HAVE_DECL_SQLITE_DBSTATUS_LOOKASIDE_USED],
             [depending on SQLite library version.])
 AH_TEMPLATE([HAVE_DECL_SQLITE_DBSTATUS_LOOKASIDE_HIT],
@@ -48,13 +58,31 @@ AC_PROG_MAKE_SET
 AC_LIBTOOL_WIN32_DLL
 AC_PROG_LIBTOOL
 
-AC_PATH_PROG(WX_CONFIG, wx-config, not_found)
-if test x$WX_CONFIG == xnot_found; then
-  AC_MSG_ERROR([cannot find wx-config (WxWidgets configuration helper), bailing out - try installing WxWidgets GTK development packages])
+AC_ARG_WITH([wxconfig],
+      [AS_HELP_STRING([--with-wxconfig=FILE], [specify an alternative wx-config file])],
+	[WXCONFIG="$withval"], [WXCONFIG=""])
+if test "x$WXCONFIG" = "x"; then
+      # WXCONFIG was not specified, so search within the current path
+      AC_PATH_PROG([WXCONFIG], [wx-config])	
+      # If we couldn't find wx-config, display an error
+      if test "x$WXCONFIG" = "x"; then
+              AC_MSG_ERROR([could not find wx-config within the current path. You may need to try re-running configure with a --with-wxconfig parameter.])
+      fi
+else
+      # WXCONFIG was specified; display a message to the user
+      if test "x$WXCONFIG" = "xyes"; then
+              AC_MSG_ERROR([you must specify a parameter to --with-wxconfig, e.g. --with-wxconfig=/path/to/wx-config])
+      else
+              if test -f $WXCONFIG; then
+                      AC_MSG_RESULT([Using user-specified wx-config file: $WXCONFIG])
+              else
+                      AC_MSG_ERROR([the user-specified wx-config file $WXCONFIG does not exist])
+              fi     
+      fi
 fi
-CXXFLAGS="$(wx-config --cxxflags)"
-AM_CXXFLAGS="$(wx-config --cxxflags)"
-WX_LIBS="$(wx-config --libs)"
+CXXFLAGS=`$WXCONFIG --cxxflags`
+AM_CXXFLAGS=`$WXCONFIG --cxxflags`
+WX_LIBS=`$WXCONFIG --libs std,aui`
 AC_SUBST(WX_LIBS)
 
 # Checks for header files.
@@ -131,12 +159,6 @@ AC_SEARCH_LIBS(GEOSTopologyPreserveSimplify,geos_c,,AC_MSG_ERROR([could not find
 LIBS="$LIBS_SAVE"
 LIBS=$LIBS$GEOS_LDFLAGS' -lgeos_c'
 
-PKG_CHECK_MODULES([LIBGAIAGRAPHICS], [gaiagraphics], , AC_MSG_ERROR(['libgaiagraphics' is required but it doesn't seem to be installed on this system.]))
-AC_SUBST(LIBGAIAGRAPHICS_CFLAGS)
-AC_SUBST(LIBGAIAGRAPHICS_LIBS)
-
-AC_CHECK_LIB(gaiagraphics,gGraphCreateSVG,,AC_MSG_ERROR([found an obsolete 'libgaiagraphics': please update to a more recent version.]),-lm)
-
 #-----------------------------------------------------------------------
 #   --enable-freexl
 #
@@ -164,6 +186,77 @@ if test x"$enable_libxml2" != "xno"; then
   AC_DEFINE(ENABLE_LIBXML2)
 fi
 
+#-----------------------------------------------------------------------
+#   --enable-openjpeg
+#
+AC_ARG_ENABLE(openjpeg, [AS_HELP_STRING(
+  [--enable-openjpeg], [enables OpenJpeg inclusion [default=yes]])],
+  [], [enable_openjpeg=yes])
+    if test x"$enable_openjpeg" != "xno"; then
+    #
+    # testing OpenJpeg-2 headers
+    # they could be either on -/include/openjpeg-2.0
+    #                   or on -/include/openjpeg-2.1
+    #
+    AC_CHECK_HEADERS(openjpeg-2.0/openjpeg.h)
+    AC_CHECK_HEADERS(openjpeg-2.1/openjpeg.h)
+    if test x"$ac_cv_header_openjpeg_2_0_openjpeg_h" != x"yes" &&
+        test x"$ac_cv_header_openjpeg_2_1_openjpeg_h" != x"yes";
+    then
+        AC_MSG_ERROR(['OpenJpeg-2' is required but the header (openjpeg.h) doesn't seem to be installed on this system])
+    fi 
+    AC_CHECK_LIB(openjp2,opj_create_decompress,,AC_MSG_ERROR(['libopenjp2' is required but it doesn't seems to be installed on this system.]),-lm)
+    # testing for OpenJpeg 2.0 or 2.1
+    AC_COMPILE_IFELSE(  [AC_LANG_PROGRAM([[#ifdef HAVE_OPENJPEG_2_1_OPENJPEG_H
+                                       #include <openjpeg-2.1/openjpeg.h>
+                                       #else
+                                       #include <openjpeg-2.0/openjpeg.h>
+                                       #endif]],
+                                     [[void *d; opj_stream_t *s; opj_stream_set_user_data (s, &d, NULL);]])],
+                    [
+                      AC_MSG_RESULT([yes])
+                      AC_DEFINE(OPENJPEG_2_1)
+                    ],
+                    [AC_MSG_RESULT([no])]
+                 )
+else
+  AC_DEFINE(OMIT_OPENJPEG)
+fi
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+#   --enable-webp
+#
+AC_ARG_ENABLE(webp, [AS_HELP_STRING(
+  [--enable-webp], [enables WebP inclusion [default=yes]])],
+  [], [enable_webp=yes])
+if test x"$enable_webp" != "xno"; then
+    PKG_CHECK_MODULES([LIBWEBP], [libwebp], , AC_MSG_ERROR(['libwebp' is required but it doesn't seems to be installed on this system.]))
+    AC_SUBST(LIBWEBP_CFLAGS)
+    AC_SUBST(LIBWEBP_LIBS)
+else
+  AC_DEFINE(OMIT_WEBP)
+fi
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+#   --enable-charls
+#
+AC_ARG_ENABLE(charls, [AS_HELP_STRING(
+  [--enable-charls], [enables CharLS inclusion [default=yes]])],
+  [], [enable_charls=yes])
+if test x"$enable_charls" != "xno"; then
+    AC_CHECK_HEADERS(CharLS/interface.h,, [AC_MSG_ERROR([cannot find CharLS/interface.h, bailing out])])
+    AC_CHECK_LIB(CharLS,JpegLsEncode,,AC_MSG_ERROR(['libCharLS' is required but it doesn't seems to be installed on this system.]),-lm)
+else
+  AC_DEFINE(OMIT_CHARLS)
+fi
+#-----------------------------------------------------------------------
+
+PKG_CHECK_MODULES([LIBLZMA], [liblzma], , AC_MSG_ERROR(['liblzma' is required but it doesn't seems to be installed on this system.]))
+AC_SUBST(LIBLZMA_CFLAGS)
+AC_SUBST(LIBLZMA_LIBS)
+    
 PKG_CHECK_MODULES([LIBSPATIALITE], [spatialite], , AC_MSG_ERROR(['libspatialite' is required but it doesn't seem to be installed on this system.]))
 AC_SUBST(LIBSPATIALITE_CFLAGS)
 # testing for libspatialite-amalgamation
@@ -172,6 +265,21 @@ if test "x$(pkg-config --cflags spatialite|grep "DSPATIALITE_AMALGAMATION=1")" !
 fi
 AC_SUBST(LIBSPATIALITE_LIBS)
 
+PKG_CHECK_MODULES([LIBRASTERLITE2], [rasterlite2], , AC_MSG_ERROR(['librasterlite2' is required but it doesn't seem to be installed on this system.]))
+AC_SUBST(LIBRASTERLITE2_CFLAGS)
+AC_SUBST(LIBRASTERLITE2_LIBS)
+
+#-----------------------------------------------------------------------
+#   --enable-rl2extra
+#
+AC_ARG_ENABLE(rl2extra, [AS_HELP_STRING(
+  [--enable-rl2extra], [enables RasterLite2 extended support [default=yes]])],
+  [], [enable_rl2extra=yes])
+if test x"$enable_rl2extra" != "xyes"; then
+  AC_DEFINE(OMIT_RL2EXTRA)
+fi
+#-----------------------------------------------------------------------
+
 AC_CONFIG_FILES([Makefile \
 	icons/Makefile \
 	win_resource/Makefile \
diff --git a/gnome_resource/Makefile.in b/gnome_resource/Makefile.in
index d3f2a11..91a7aac 100644
--- a/gnome_resource/Makefile.in
+++ b/gnome_resource/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.12.2 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2012 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,23 +14,61 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \	]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -50,7 +88,6 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = gnome_resource
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -58,10 +95,23 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
 SOURCES =
 DIST_SOURCES =
 am__can_run_installinfo = \
@@ -69,9 +119,12 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -112,13 +165,17 @@ LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBFREEXL_CFLAGS = @LIBFREEXL_CFLAGS@
 LIBFREEXL_LIBS = @LIBFREEXL_LIBS@
-LIBGAIAGRAPHICS_CFLAGS = @LIBGAIAGRAPHICS_CFLAGS@
-LIBGAIAGRAPHICS_LIBS = @LIBGAIAGRAPHICS_LIBS@
+LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
+LIBLZMA_LIBS = @LIBLZMA_LIBS@
 LIBOBJS = @LIBOBJS@
+LIBRASTERLITE2_CFLAGS = @LIBRASTERLITE2_CFLAGS@
+LIBRASTERLITE2_LIBS = @LIBRASTERLITE2_LIBS@
 LIBS = @LIBS@
 LIBSPATIALITE_CFLAGS = @LIBSPATIALITE_CFLAGS@
 LIBSPATIALITE_LIBS = @LIBSPATIALITE_LIBS@
 LIBTOOL = @LIBTOOL@
+LIBWEBP_CFLAGS = @LIBWEBP_CFLAGS@
+LIBWEBP_LIBS = @LIBWEBP_LIBS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -152,7 +209,7 @@ SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 VERSION = @VERSION@
-WX_CONFIG = @WX_CONFIG@
+WXCONFIG = @WXCONFIG@
 WX_LIBS = @WX_LIBS@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
@@ -223,7 +280,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gnome_resource/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu gnome_resource/Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -247,11 +303,9 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
-tags: TAGS
-TAGS:
+tags TAGS:
 
-ctags: CTAGS
-CTAGS:
+ctags CTAGS:
 
 cscope cscopelist:
 
@@ -389,15 +443,18 @@ uninstall-am:
 .MAKE: install-am install-strip
 
 .PHONY: all all-am check check-am clean clean-generic clean-libtool \
-	distclean distclean-generic distclean-libtool distdir dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-dvi install-dvi-am \
-	install-exec install-exec-am install-html install-html-am \
-	install-info install-info-am install-man install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/icons/AttributionDisclaimer.txt b/icons/AttributionDisclaimer.txt
new file mode 100644
index 0000000..0ef1abf
--- /dev/null
+++ b/icons/AttributionDisclaimer.txt
@@ -0,0 +1,29 @@
+ATTRIBUTION DISCLAIMER
+
+All Icons used by spatialite_gui derive from the following
+original work released on CC-BY terms:
+
+----------------------------------------------------------
+
+Silk icon set 1.3
+
+_________________________________________
+Mark James
+http://www.famfamfam.com/lab/icons/silk/
+_________________________________________
+
+This work is licensed under a
+Creative Commons Attribution 2.5 License.
+[ http://creativecommons.org/licenses/by/2.5/ ]
+
+This means you may use it for any purpose,
+and make any changes you like.
+All I ask is that you include a link back
+to this page in your credits.
+
+Are you using this icon set? Send me an email
+(including a link or picture if available) to
+mjames at gmail.com
+
+Any other questions about this icon set please
+contact mjames at gmail.com
diff --git a/icons/Makefile.am b/icons/Makefile.am
index 94e7597..e09bf36 100644
--- a/icons/Makefile.am
+++ b/icons/Makefile.am
@@ -13,4 +13,6 @@ EXTRA_DIST = about.xpm charset.xpm column.xpm composer.xpm connect.xpm \
 	topology.xpm tmp_table.xpm tmp_view.xpm trigger.xpm vacuum.xpm \
 	view.xpm virtdbf.xpm virtshp.xpm virttxt.xpm virtxl.xpm vtable.xpm \
 	attach.xpm sql_log.xpm db_status.xpm loadxml.xpm checkgeom.xpm \
-	sanegeom.xpm wfs.xpm dxf.xpm
+	sanegeom.xpm wfs.xpm dxf.xpm connect_ro.xpm coverage.xpm \
+	coverage_tiles.xpm security_relaxed.xpm security_lock.xpm \
+	security_rdonly.xpm vector.xpm AttributionDisclaimer.txt
diff --git a/icons/Makefile.in b/icons/Makefile.in
index 62219dc..338b728 100644
--- a/icons/Makefile.in
+++ b/icons/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.12.2 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2012 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,23 +14,61 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \	]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -50,7 +88,6 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = icons
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -58,10 +95,23 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
 SOURCES =
 DIST_SOURCES =
 am__can_run_installinfo = \
@@ -69,9 +119,12 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -112,13 +165,17 @@ LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBFREEXL_CFLAGS = @LIBFREEXL_CFLAGS@
 LIBFREEXL_LIBS = @LIBFREEXL_LIBS@
-LIBGAIAGRAPHICS_CFLAGS = @LIBGAIAGRAPHICS_CFLAGS@
-LIBGAIAGRAPHICS_LIBS = @LIBGAIAGRAPHICS_LIBS@
+LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
+LIBLZMA_LIBS = @LIBLZMA_LIBS@
 LIBOBJS = @LIBOBJS@
+LIBRASTERLITE2_CFLAGS = @LIBRASTERLITE2_CFLAGS@
+LIBRASTERLITE2_LIBS = @LIBRASTERLITE2_LIBS@
 LIBS = @LIBS@
 LIBSPATIALITE_CFLAGS = @LIBSPATIALITE_CFLAGS@
 LIBSPATIALITE_LIBS = @LIBSPATIALITE_LIBS@
 LIBTOOL = @LIBTOOL@
+LIBWEBP_CFLAGS = @LIBWEBP_CFLAGS@
+LIBWEBP_LIBS = @LIBWEBP_LIBS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -152,7 +209,7 @@ SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 VERSION = @VERSION@
-WX_CONFIG = @WX_CONFIG@
+WXCONFIG = @WXCONFIG@
 WX_LIBS = @WX_LIBS@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
@@ -221,7 +278,9 @@ EXTRA_DIST = about.xpm charset.xpm column.xpm composer.xpm connect.xpm \
 	topology.xpm tmp_table.xpm tmp_view.xpm trigger.xpm vacuum.xpm \
 	view.xpm virtdbf.xpm virtshp.xpm virttxt.xpm virtxl.xpm vtable.xpm \
 	attach.xpm sql_log.xpm db_status.xpm loadxml.xpm checkgeom.xpm \
-	sanegeom.xpm wfs.xpm dxf.xpm
+	sanegeom.xpm wfs.xpm dxf.xpm connect_ro.xpm coverage.xpm \
+	coverage_tiles.xpm security_relaxed.xpm security_lock.xpm \
+	security_rdonly.xpm vector.xpm AttributionDisclaimer.txt
 
 all: all-am
 
@@ -238,7 +297,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu icons/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu icons/Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -262,11 +320,9 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
-tags: TAGS
-TAGS:
+tags TAGS:
 
-ctags: CTAGS
-CTAGS:
+ctags CTAGS:
 
 cscope cscopelist:
 
@@ -404,15 +460,18 @@ uninstall-am:
 .MAKE: install-am install-strip
 
 .PHONY: all all-am check check-am clean clean-generic clean-libtool \
-	distclean distclean-generic distclean-libtool distdir dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-dvi install-dvi-am \
-	install-exec install-exec-am install-html install-html-am \
-	install-info install-info-am install-man install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/icons/connect_ro.xpm b/icons/connect_ro.xpm
new file mode 100644
index 0000000..31e0dd8
--- /dev/null
+++ b/icons/connect_ro.xpm
@@ -0,0 +1,146 @@
+/* XPM */
+static const char * connect_ro_xpm[] = {
+"16 16 127 2",
+"  	c None",
+". 	c #BABABA",
+"+ 	c #B8B8B8",
+"@ 	c #B7B7B7",
+"# 	c #B6B6B6",
+"$ 	c #B4B4B4",
+"% 	c #B3B3B3",
+"& 	c #BBBBBB",
+"* 	c #D0D0D0",
+"= 	c #E8E8E8",
+"- 	c #F3F3F3",
+"; 	c #FDFDFD",
+"> 	c #FCFCFC",
+", 	c #EDEDED",
+"' 	c #E0E0E0",
+") 	c #C2C2C2",
+"! 	c #ADADAD",
+"~ 	c #E1E1E1",
+"{ 	c #FEFEFE",
+"] 	c #FFFFFF",
+"^ 	c #FBFBFB",
+"/ 	c #CFCFCF",
+"( 	c #A9A9A9",
+"_ 	c #B9B9B9",
+": 	c #F8F8F8",
+"< 	c #EAEAEA",
+"[ 	c #A7A7A7",
+"} 	c #F7F7F7",
+"| 	c #E7E7E7",
+"1 	c #EFEFEF",
+"2 	c #F6F6F6",
+"3 	c #FAFAFA",
+"4 	c #F0F0F0",
+"5 	c #DEDEDE",
+"6 	c #C3C3C3",
+"7 	c #E6E6E6",
+"8 	c #A5A5A5",
+"9 	c #B5B5B5",
+"0 	c #EBEBEB",
+"a 	c #D6D6D6",
+"b 	c #D5D5D5",
+"c 	c #D1D1D1",
+"d 	c #BCBCBC",
+"e 	c #C0C0C0",
+"f 	c #E5E5E5",
+"g 	c #A3A3A3",
+"h 	c #F5F5F5",
+"i 	c #EEEEEE",
+"j 	c #E2E2E2",
+"k 	c #CDCDCD",
+"l 	c #E3E2E2",
+"m 	c #C19C62",
+"n 	c #E1AB46",
+"o 	c #B2B2B2",
+"p 	c #F4F4F4",
+"q 	c #DDDDDD",
+"r 	c #E3E3E3",
+"s 	c #C9C9C9",
+"t 	c #BDBDBD",
+"u 	c #BFBFBF",
+"v 	c #DEBE91",
+"w 	c #ECC96F",
+"x 	c #FBF3C9",
+"y 	c #E7BA57",
+"z 	c #B0B0B0",
+"A 	c #D9D9D9",
+"B 	c #DBDBDB",
+"C 	c #C4C4C4",
+"D 	c #C7AC83",
+"E 	c #EAC15E",
+"F 	c #FBF0A3",
+"G 	c #F0D480",
+"H 	c #ECC77E",
+"I 	c #DDA350",
+"J 	c #AEAEAE",
+"K 	c #F2F2F2",
+"L 	c #D8D8D8",
+"M 	c #DCDCDC",
+"N 	c #D1A862",
+"O 	c #F9EEA9",
+"P 	c #F8E67E",
+"Q 	c #F8E89A",
+"R 	c #F0D17E",
+"S 	c #F6E280",
+"T 	c #D9983F",
+"U 	c #ACACAC",
+"V 	c #D4D4D4",
+"W 	c #D2D2D2",
+"X 	c #C7A570",
+"Y 	c #F4DD89",
+"Z 	c #F6E06A",
+"` 	c #F7E273",
+" .	c #F6DF5F",
+"..	c #F6DA55",
+"+.	c #CD7F38",
+"@.	c #C5B7A2",
+"#.	c #DCB061",
+"$.	c #E5BE63",
+"%.	c #F2D95E",
+"&.	c #F6DB4E",
+"*.	c #F7DD5B",
+"=.	c #F5D855",
+"-.	c #CD802E",
+";.	c #CECECE",
+">.	c #EBD3AD",
+",.	c #E0AE5D",
+"'.	c #F6E299",
+").	c #F5DC53",
+"!.	c #F6D946",
+"~.	c #CB9038",
+"{.	c #CF8335",
+"].	c #D28436",
+"^.	c #A1A1A1",
+"/.	c #9F9F9F",
+"(.	c #ABABAB",
+"_.	c #D6AA5A",
+":.	c #F8E6A1",
+"<.	c #F2D238",
+"[.	c #F6D647",
+"}.	c #CD943B",
+"|.	c #DFAD4B",
+"1.	c #F9E986",
+"2.	c #F5D94D",
+"3.	c #CC923A",
+"4.	c #C98D34",
+"5.	c #D59F45",
+"6.	c #CB8D3A",
+"      . + @ # $ %               ",
+"  & * = - ; > , ' ) !           ",
+". ~ { ] ] ] ] ] ] ^ / (         ",
+"_ : { ] ] ] ] ] ] ^ < [         ",
+"@ } | 1 2 ^ 3 4 5 6 7 8         ",
+"9 2 0 5 a b c 6 d e f g         ",
+"$ h i 7 j 7 ~ k ) ) l m n       ",
+"o p < ~ q r 5 s t u v w x y     ",
+"z - | q A ' B C + D E F G H I   ",
+"J K j L b M L e % N O P Q R S T ",
+"U 4 5 V W B a u z X Y Z `  ...+.",
+"( 5 - B W B a @.#.$.%.&.*.=.-.  ",
+"  8 ;., p h >.,.'.).!.~.{.].    ",
+"    ^./.^.(._.:.<.[.}.          ",
+"            |.1.2.3.            ",
+"            4.5.6.              "};
diff --git a/icons/coverage.xpm b/icons/coverage.xpm
new file mode 100644
index 0000000..92d4750
--- /dev/null
+++ b/icons/coverage.xpm
@@ -0,0 +1,154 @@
+/* XPM */
+static const char * coverage_xpm[] = {
+"16 16 135 2",
+"  	c None",
+". 	c #A1B3CE",
+"+ 	c #9FB1CF",
+"@ 	c #95ABCD",
+"# 	c #8EA7CD",
+"$ 	c #8EA6CD",
+"% 	c #93AACD",
+"& 	c #9BAFCD",
+"* 	c #9FB2CF",
+"= 	c #EBECEC",
+"- 	c #F3F4F4",
+"; 	c #F4F5F7",
+"> 	c #ECF3F7",
+", 	c #E9EFF2",
+"' 	c #97ADCE",
+") 	c #F2F3F4",
+"! 	c #95B4E3",
+"~ 	c #8DB4D0",
+"{ 	c #80B5A9",
+"] 	c #A1CC93",
+"^ 	c #AAD184",
+"/ 	c #A6D082",
+"( 	c #94C28B",
+"_ 	c #699E9A",
+": 	c #739DC3",
+"< 	c #779DD6",
+"[ 	c #EBF2F7",
+"} 	c #94ABCF",
+"| 	c #8FA7CD",
+"1 	c #97B5E3",
+"2 	c #87B7B8",
+"3 	c #A1CB93",
+"4 	c #A8D274",
+"5 	c #9BCB67",
+"6 	c #97C863",
+"7 	c #98C96A",
+"8 	c #8BBB83",
+"9 	c #6A99A5",
+"0 	c #7A9FD7",
+"a 	c #E9F0F7",
+"b 	c #F2F5F7",
+"c 	c #99B7E4",
+"d 	c #80B6A3",
+"e 	c #A7D082",
+"f 	c #98C965",
+"g 	c #91C65D",
+"h 	c #8BC259",
+"i 	c #87C158",
+"j 	c #8EC271",
+"k 	c #5F928C",
+"l 	c #7DA2D9",
+"m 	c #E8F0F6",
+"n 	c #94ABCE",
+"o 	c #F0F5F7",
+"p 	c #9BB8E5",
+"q 	c #7FB3A1",
+"r 	c #A0CD7D",
+"s 	c #90C55E",
+"t 	c #87C056",
+"u 	c #81BE52",
+"v 	c #7EBC52",
+"w 	c #87BD6C",
+"x 	c #5E9089",
+"y 	c #81A4DA",
+"z 	c #E7EFF5",
+"A 	c #EFF4F7",
+"B 	c #9DB9E6",
+"C 	c #87B3B6",
+"D 	c #93C288",
+"E 	c #8FC563",
+"F 	c #80BE53",
+"G 	c #7ABA4F",
+"H 	c #7FBD58",
+"I 	c #7CB078",
+"J 	c #6A96A3",
+"K 	c #84A7DC",
+"L 	c #E7EEF6",
+"M 	c #EEF3F7",
+"N 	c #9FBBE7",
+"O 	c #93B6D1",
+"P 	c #78AA9F",
+"Q 	c #87B26F",
+"R 	c #8ABD65",
+"S 	c #87BB61",
+"T 	c #7BAB6B",
+"U 	c #649391",
+"V 	c #7DA2C5",
+"W 	c #88A9DD",
+"X 	c #EDF2F7",
+"Y 	c #A1BDE8",
+"Z 	c #92B3D0",
+"` 	c #76825E",
+" .	c #868E44",
+"..	c #878B41",
+"+.	c #808356",
+"@.	c #82A6C7",
+"#.	c #8EAEE0",
+"$.	c #8BACDE",
+"%.	c #E6EEF6",
+"&.	c #ECF1F7",
+"*.	c #7AAA4E",
+"=.	c #77A84C",
+"-.	c #74A64A",
+";.	c #9A7B35",
+">.	c #D39F54",
+",.	c #D19F54",
+"'.	c #AF863F",
+").	c #679A40",
+"!.	c #65983E",
+"~.	c #63963C",
+"{.	c #8DA6CC",
+"].	c #EDF1F7",
+"^.	c #C2DCBF",
+"/.	c #C5D3AF",
+"(.	c #C9C89C",
+"_.	c #D1AF6E",
+":.	c #C3D9BA",
+"<.	c #E6EDF6",
+"[.	c #93AACE",
+"}.	c #8EA6CC",
+"|.	c #EDF1F6",
+"1.	c #E6EDF7",
+"2.	c #96ABCD",
+"3.	c #EDEFF1",
+"4.	c #F1F3F7",
+"5.	c #F1F4F8",
+"6.	c #F0F4F8",
+"7.	c #F0F4F7",
+"8.	c #F0F3F7",
+"9.	c #EFF3F7",
+"0.	c #EFF3F8",
+"a.	c #EBEFF2",
+"b.	c #97ADCF",
+"c.	c #9CAFCE",
+"d.	c #9AAECF",
+"                                ",
+"  . + @ # # # # # $ $ $ $ % &   ",
+"  * = - ; ; ; ; ; ; ; ; > , '   ",
+"  @ ) ! ~ { ] ^ / ( _ : < [ }   ",
+"  | ; 1 2 3 4 5 6 7 8 9 0 a }   ",
+"  | b c d e f g h i j k l m n   ",
+"  | o p q r s t u v w x y z n   ",
+"  | A B C D E F G H I J K L n   ",
+"  | M N O P Q R S T U V W L n   ",
+"  # X Y N Z `  ...+. at .#.$.%.n   ",
+"  # &.*.=.-.;.>.,.'.).!.~.%.n   ",
+"  {.].^.^.^./.(._.:.^.^.^.<.[.  ",
+"  }.|.^.^.^.^.^.^.^.^.^.^.1.[.  ",
+"  2.3.4.5.6.7.8.9.9.9.9.0.a.b.  ",
+"  c.d.n [.[.[.[.[.[.[.[.[.' c.  ",
+"                                "};
diff --git a/icons/coverage_tiles.xpm b/icons/coverage_tiles.xpm
new file mode 100644
index 0000000..60c2785
--- /dev/null
+++ b/icons/coverage_tiles.xpm
@@ -0,0 +1,133 @@
+/* XPM */
+static const char * coverage_tiles_xpm[] = {
+"16 16 114 2",
+"  	c None",
+". 	c #AA7128",
+"+ 	c #A96F27",
+"@ 	c #A76E26",
+"# 	c #A56C25",
+"$ 	c #A36A23",
+"% 	c #A06822",
+"& 	c #9D6620",
+"* 	c #9B641F",
+"= 	c #98611D",
+"- 	c #955F1C",
+"; 	c #A86F26",
+"> 	c #DDA252",
+", 	c #DA934D",
+"' 	c #D59243",
+") 	c #D1913C",
+"! 	c #CD8E3C",
+"~ 	c #CB8B3A",
+"{ 	c #BE843E",
+"] 	c #CA924B",
+"^ 	c #905B19",
+"/ 	c #D8903F",
+"( 	c #61BCF3",
+"_ 	c #62BDF3",
+": 	c #5DB8F1",
+"< 	c #4DA6E9",
+"[ 	c #368EDE",
+"} 	c #CA9249",
+"| 	c #8C5817",
+"1 	c #A26A23",
+"2 	c #DD9148",
+"3 	c #5CB6F0",
+"4 	c #5EB8F1",
+"5 	c #5CB7F0",
+"6 	c #A47536",
+"7 	c #A27234",
+"8 	c #9F7032",
+"9 	c #A86E26",
+"0 	c #A16922",
+"a 	c #9E6721",
+"b 	c #D98F46",
+"c 	c #4BA4E8",
+"d 	c #4FA8EA",
+"e 	c #4CA5E8",
+"f 	c #A17233",
+"g 	c #D2A15B",
+"h 	c #CE9256",
+"i 	c #D49244",
+"j 	c #CC8D39",
+"k 	c #9A631F",
+"l 	c #D48A43",
+"m 	c #368DDE",
+"n 	c #3890DF",
+"o 	c #9B6F35",
+"p 	c #CC8F49",
+"q 	c #35C62D",
+"r 	c #40C723",
+"s 	c #3CC321",
+"t 	c #3BCD27",
+"u 	c #43D12E",
+"v 	c #57DA3F",
+"w 	c #96601C",
+"x 	c #CC8A43",
+"y 	c #6EE454",
+"z 	c #CF9037",
+"A 	c #885514",
+"B 	c #925D1A",
+"C 	c #8F5A18",
+"D 	c #6EE46E",
+"E 	c #CA8B51",
+"F 	c #845112",
+"G 	c #38BAED",
+"H 	c #58BFFF",
+"I 	c #62BBFF",
+"J 	c #44B6FF",
+"K 	c #DBEB8C",
+"L 	c #FFFF6D",
+"M 	c #78EF69",
+"N 	c #CE8F45",
+"O 	c #804E10",
+"P 	c #3BCE45",
+"Q 	c #07BE31",
+"R 	c #5AB7FF",
+"S 	c #58B6FF",
+"T 	c #97D1CC",
+"U 	c #F3FA8A",
+"V 	c #C99A40",
+"W 	c #C7883D",
+"X 	c #7D4C0E",
+"Y 	c #4BC84F",
+"Z 	c #36CB21",
+"` 	c #42C825",
+" .	c #54B8AC",
+"..	c #42A6FF",
+"+.	c #00A2FF",
+"@.	c #7E4D0F",
+"#.	c #7C4B0E",
+"$.	c #7A490D",
+"%.	c #77F35E",
+"&.	c #A4FF8C",
+"*.	c #ACFF77",
+"=.	c #7CF634",
+"-.	c #75EF55",
+";.	c #64FF79",
+">.	c #C59046",
+",.	c #C6954A",
+"'.	c #E8D462",
+").	c #E9D461",
+"!.	c #C99644",
+"~.	c #8C5816",
+"{.	c #895515",
+"].	c #865313",
+"^.	c #835112",
+"/.	c #804F10",
+"                                ",
+". + @ # $ % & * = -             ",
+"; > , ' ) ! ~ { ] ^             ",
+"# / ( _ ( : < [ } |             ",
+"1 2 3 4 5 6 7 8 9 0 % & * = -   ",
+"a b c d e f g h i j ! ~ { ] ^   ",
+"k l m n [ o p q r s t u v } |   ",
+"w x . + @ # $ % & * = - y z A   ",
+"B C ; > , ' ) ! ~ { ] ^ D E F   ",
+"    # / G H I J K L } | M N O   ",
+"    1 2 P Q R S T U z A V W X   ",
+"    a b Y Z `  ...+.E F @.#.$.  ",
+"    k l %.&.*.=.-.;.N O         ",
+"    w x >.,.'.).!.V W X         ",
+"    B C ~.{.].^./. at .#.$.        ",
+"                                "};
diff --git a/icons/security_lock.xpm b/icons/security_lock.xpm
new file mode 100644
index 0000000..7ca6978
--- /dev/null
+++ b/icons/security_lock.xpm
@@ -0,0 +1,187 @@
+/* XPM */
+static const char * security_lock_xpm[] = {
+"16 16 168 2",
+"  	c None",
+". 	c #A3A3A3",
+"+ 	c #A0A0A0",
+"@ 	c #9D9D9D",
+"# 	c #9A9A9A",
+"$ 	c #979797",
+"% 	c #949494",
+"& 	c #A2A2A2",
+"* 	c #BCBCBC",
+"= 	c #CACACA",
+"- 	c #CCCCCC",
+"; 	c #C2C2C2",
+"> 	c #ADADAD",
+", 	c #8C8C8C",
+"' 	c #A1A1A1",
+") 	c #C4C4C4",
+"! 	c #BEBEBE",
+"~ 	c #969696",
+"{ 	c #939393",
+"] 	c #AEAEAE",
+"^ 	c #848484",
+"/ 	c #BABABA",
+"( 	c #BFBFBF",
+"_ 	c #989898",
+": 	c #878787",
+"< 	c #A8A8A8",
+"[ 	c #9E9E9E",
+"} 	c #898989",
+"| 	c #A9A9A9",
+"1 	c #797979",
+"2 	c #999999",
+"3 	c #C6C6C6",
+"4 	c #7D7D7D",
+"5 	c #ABABAB",
+"6 	c #767676",
+"7 	c #E1C361",
+"8 	c #A8A088",
+"9 	c #919191",
+"0 	c #8E8E8E",
+"a 	c #DCB95A",
+"b 	c #DFB855",
+"c 	c #DEB551",
+"d 	c #DDB14D",
+"e 	c #DCAD49",
+"f 	c #D7A846",
+"g 	c #787878",
+"h 	c #8D7E65",
+"i 	c #D89931",
+"j 	c #E1C260",
+"k 	c #FCF3C9",
+"l 	c #FDF3CB",
+"m 	c #FEF6D4",
+"n 	c #FFF6D7",
+"o 	c #FFF4D8",
+"p 	c #FFF8E0",
+"q 	c #FFF8DF",
+"r 	c #FFF5DA",
+"s 	c #FCF1CD",
+"t 	c #FAEDC2",
+"u 	c #FAEBBD",
+"v 	c #D6932B",
+"w 	c #E0BF5C",
+"x 	c #FCF3C8",
+"y 	c #F9DF75",
+"z 	c #FDE689",
+"A 	c #FFE795",
+"B 	c #FFE59A",
+"C 	c #FFEEAA",
+"D 	c #FFEDA8",
+"E 	c #FFE399",
+"F 	c #F9D574",
+"G 	c #F3CC59",
+"H 	c #F1C84F",
+"I 	c #FAE9BB",
+"J 	c #D58D24",
+"K 	c #DFBB58",
+"L 	c #FCF1C7",
+"M 	c #F9DC6F",
+"N 	c #EDBB56",
+"O 	c #EFBD61",
+"P 	c #FFE79B",
+"Q 	c #E2A635",
+"R 	c #E1A44B",
+"S 	c #FFE290",
+"T 	c #E9AD49",
+"U 	c #E3A438",
+"V 	c #F0C449",
+"W 	c #F9E8B8",
+"X 	c #D4881E",
+"Y 	c #DEB753",
+"Z 	c #FCF0C6",
+"` 	c #F8D96A",
+" .	c #FDE27C",
+"..	c #FFE890",
+"+.	c #FFE999",
+"@.	c #DF9F32",
+"#.	c #B28B54",
+"$.	c #FFE28A",
+"%.	c #F9D06A",
+"&.	c #F1C550",
+"*.	c #F0C146",
+"=.	c #F9E7B6",
+"-.	c #D38318",
+";.	c #DDB24E",
+">.	c #FBEFC3",
+",.	c #F8D665",
+"'.	c #ECB64C",
+").	c #EFBD5A",
+"!.	c #FFEB95",
+"~.	c #DD9730",
+"{.	c #AB824D",
+"].	c #FFE184",
+"^.	c #E9A941",
+"/.	c #E19F32",
+"(.	c #EFBE42",
+"_.	c #F9E5B4",
+":.	c #D27E13",
+"<.	c #FBEEC1",
+"[.	c #F7D35F",
+"}.	c #FCDB6C",
+"|.	c #FFE57F",
+"1.	c #FFED8F",
+"2.	c #FFF297",
+"3.	c #FFED93",
+"4.	c #FFDF7C",
+"5.	c #F8CC5B",
+"6.	c #EFBE46",
+"7.	c #EEBA3C",
+"8.	c #F9E3B3",
+"9.	c #D1790E",
+"0.	c #DBA843",
+"a.	c #FBECBF",
+"b.	c #F5CF59",
+"c.	c #ECB041",
+"d.	c #EFBA4E",
+"e.	c #EFC25A",
+"f.	c #EFC660",
+"g.	c #EFC45C",
+"h.	c #EFB64C",
+"i.	c #E6A537",
+"j.	c #E19A2A",
+"k.	c #EEB838",
+"l.	c #F8E3B1",
+"m.	c #D07509",
+"n.	c #DAA33D",
+"o.	c #FAEBBC",
+"p.	c #FCEBBC",
+"q.	c #FEEEBF",
+"r.	c #FFF4C6",
+"s.	c #FFF8CE",
+"t.	c #FFFAD3",
+"u.	c #FFF8D0",
+"v.	c #FFF2C7",
+"w.	c #FCE9BA",
+"x.	c #F9E4B3",
+"y.	c #F8E2B0",
+"z.	c #CF7105",
+"A.	c #D99D36",
+"B.	c #D7942C",
+"C.	c #D69028",
+"D.	c #D58C23",
+"E.	c #D3841A",
+"F.	c #D28015",
+"G.	c #D17C11",
+"H.	c #D0760A",
+"I.	c #CF7307",
+"J.	c #CF7004",
+"K.	c #CE6E01",
+"          . + @ # $ %           ",
+"        & * = - = ; > ,         ",
+"      ' ) ! ' ~ { $ ] ] ^       ",
+"      / ( _         : < [       ",
+"    @ ) '             } | 1     ",
+"    2 3 %             4 5 6     ",
+"  7 8 9 0 a b c d e f g 6 h i   ",
+"  j k l m n o p q r s t u u v   ",
+"  w x y z A B C D E F G H I J   ",
+"  K L M N O P Q R S T U V W X   ",
+"  Y Z `  ...+. at .#.$.%.&.*.=.-.  ",
+"  ;.>.,.'.).!.~.{.].^./.(._.:.  ",
+"  e <.[.}.|.1.2.3.4.5.6.7.8.9.  ",
+"  0.a.b.c.d.e.f.g.h.i.j.k.l.m.  ",
+"  n.o.p.q.r.s.t.u.v.w.x.y.y.z.  ",
+"  A.i B.C.D.X E.F.G.9.H.I.J.K.  "};
diff --git a/icons/security_rdonly.xpm b/icons/security_rdonly.xpm
new file mode 100644
index 0000000..ca9a9e1
--- /dev/null
+++ b/icons/security_rdonly.xpm
@@ -0,0 +1,189 @@
+/* XPM */
+static const char * security_rdonly_xpm[] = {
+"16 16 170 2",
+"  	c None",
+". 	c #A3A3A3",
+"+ 	c #A0A0A0",
+"@ 	c #9D9D9D",
+"# 	c #9A9A9A",
+"$ 	c #979797",
+"% 	c #949494",
+"& 	c #A2A2A2",
+"* 	c #BCBCBC",
+"= 	c #CACACA",
+"- 	c #CCCCCC",
+"; 	c #C2C2C2",
+"> 	c #ADADAD",
+", 	c #8C8C8C",
+"' 	c #A1A1A1",
+") 	c #C4C4C4",
+"! 	c #BEBEBE",
+"~ 	c #969696",
+"{ 	c #939393",
+"] 	c #AEAEAE",
+"^ 	c #848484",
+"/ 	c #BABABA",
+"( 	c #BFBFBF",
+"_ 	c #989898",
+": 	c #878787",
+"< 	c #A8A8A8",
+"[ 	c #9E9E9E",
+"} 	c #898989",
+"| 	c #A9A9A9",
+"1 	c #797979",
+"2 	c #999999",
+"3 	c #C6C6C6",
+"4 	c #7D7D7D",
+"5 	c #ABABAB",
+"6 	c #767676",
+"7 	c #E1C361",
+"8 	c #A8A088",
+"9 	c #919191",
+"0 	c #8E8E8E",
+"a 	c #DCB95A",
+"b 	c #DFB855",
+"c 	c #DEB551",
+"d 	c #DDB14D",
+"e 	c #DCAD49",
+"f 	c #D7A846",
+"g 	c #787878",
+"h 	c #8D7E65",
+"i 	c #D89931",
+"j 	c #E1C260",
+"k 	c #FCF3C9",
+"l 	c #FDF3CB",
+"m 	c #FEF6D4",
+"n 	c #FFF6D7",
+"o 	c #FFF4D8",
+"p 	c #FFF8E0",
+"q 	c #FFF8DF",
+"r 	c #FFF5DA",
+"s 	c #FCF1CD",
+"t 	c #FAEDC2",
+"u 	c #FAEBBD",
+"v 	c #D6932B",
+"w 	c #E0BF5C",
+"x 	c #FCF3C8",
+"y 	c #F9DF75",
+"z 	c #FDE689",
+"A 	c #FFE795",
+"B 	c #FFE59A",
+"C 	c #FFEEAA",
+"D 	c #FFEDA8",
+"E 	c #FFE399",
+"F 	c #F9D574",
+"G 	c #F3CC59",
+"H 	c #F1C84F",
+"I 	c #FAE9BB",
+"J 	c #D58D24",
+"K 	c #DFBB58",
+"L 	c #FCF1C7",
+"M 	c #F9DC6F",
+"N 	c #EDBB56",
+"O 	c #EFBD61",
+"P 	c #FFE79B",
+"Q 	c #E2A635",
+"R 	c #E1A44B",
+"S 	c #FFE290",
+"T 	c #D88535",
+"U 	c #C45713",
+"V 	c #BC4304",
+"W 	c #C05818",
+"X 	c #C76811",
+"Y 	c #DEB753",
+"Z 	c #FCF0C6",
+"` 	c #F8D96A",
+" .	c #FDE27C",
+"..	c #FFE890",
+"+.	c #FFE999",
+"@.	c #DF9F32",
+"#.	c #B28B54",
+"$.	c #E3A158",
+"%.	c #D27539",
+"&.	c #F7B58D",
+"*.	c #FED6B8",
+"=.	c #F5A872",
+"-.	c #CB6B2D",
+";.	c #DDB24E",
+">.	c #FBEFC3",
+",.	c #F8D665",
+"'.	c #ECB64C",
+").	c #EFBD5A",
+"!.	c #FFEB95",
+"~.	c #DD9730",
+"{.	c #AB824D",
+"].	c #C25914",
+"^.	c #F6B58D",
+"/.	c #FF924D",
+"(.	c #FF7711",
+"_.	c #FF8621",
+":.	c #EB8A40",
+"<.	c #B94403",
+"[.	c #FBEEC1",
+"}.	c #F7D35F",
+"|.	c #FCDB6C",
+"1.	c #FFE57F",
+"2.	c #FFED8F",
+"3.	c #FFF297",
+"4.	c #FFED93",
+"5.	c #FECDAE",
+"6.	c #FFFFFF",
+"7.	c #EF7F18",
+"8.	c #BC4204",
+"9.	c #DBA843",
+"0.	c #FBECBF",
+"a.	c #F5CF59",
+"b.	c #ECB041",
+"c.	c #EFBA4E",
+"d.	c #EFC25A",
+"e.	c #EFC660",
+"f.	c #EFC45C",
+"g.	c #BF510B",
+"h.	c #F49D63",
+"i.	c #FF7F18",
+"j.	c #F87600",
+"k.	c #EE7600",
+"l.	c #E16803",
+"m.	c #B94503",
+"n.	c #DAA33D",
+"o.	c #FAEBBC",
+"p.	c #FCEBBC",
+"q.	c #FEEEBF",
+"r.	c #FFF4C6",
+"s.	c #FFF8CE",
+"t.	c #FFFAD3",
+"u.	c #FFF8D0",
+"v.	c #E1A470",
+"w.	c #CA6627",
+"x.	c #E67721",
+"y.	c #EA7905",
+"z.	c #DD6401",
+"A.	c #BD4D04",
+"B.	c #D99D36",
+"C.	c #D7942C",
+"D.	c #D69028",
+"E.	c #D58C23",
+"F.	c #D4881E",
+"G.	c #D3841A",
+"H.	c #D28015",
+"I.	c #D17C11",
+"J.	c #CB6915",
+"K.	c #BC4B04",
+"L.	c #BB4A03",
+"M.	c #C35A02",
+"          . + @ # $ %           ",
+"        & * = - = ; > ,         ",
+"      ' ) ! ' ~ { $ ] ] ^       ",
+"      / ( _         : < [       ",
+"    @ ) '             } | 1     ",
+"    2 3 %             4 5 6     ",
+"  7 8 9 0 a b c d e f g 6 h i   ",
+"  j k l m n o p q r s t u u v   ",
+"  w x y z A B C D E F G H I J   ",
+"  K L M N O P Q R S T U V W X   ",
+"  Y Z `  ...+. at .#.$.%.&.*.=.-.  ",
+"  ;.>.,.'.).!.~.{.].^./.(._.:.<.",
+"  e [.}.|.1.2.3.4.V 5.6.6.6.7.8.",
+"  9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.",
+"  n.o.p.q.r.s.t.u.v.w.x.y.z.A.  ",
+"  B.i C.D.E.F.G.H.I.J.K.8.L.M.  "};
diff --git a/icons/security_relaxed.xpm b/icons/security_relaxed.xpm
new file mode 100644
index 0000000..990c675
--- /dev/null
+++ b/icons/security_relaxed.xpm
@@ -0,0 +1,193 @@
+/* XPM */
+static const char * security_relaxed_xpm[] = {
+"16 16 174 2",
+"  	c None",
+". 	c #A3A3A3",
+"+ 	c #A0A0A0",
+"@ 	c #9D9D9D",
+"# 	c #9A9A9A",
+"$ 	c #979797",
+"% 	c #949494",
+"& 	c #A2A2A2",
+"* 	c #BCBCBC",
+"= 	c #CACACA",
+"- 	c #CCCCCC",
+"; 	c #C2C2C2",
+"> 	c #ADADAD",
+", 	c #8C8C8C",
+"' 	c #A1A1A1",
+") 	c #C4C4C4",
+"! 	c #BEBEBE",
+"~ 	c #969696",
+"{ 	c #939393",
+"] 	c #AEAEAE",
+"^ 	c #848484",
+"/ 	c #BABABA",
+"( 	c #BFBFBF",
+"_ 	c #989898",
+": 	c #878787",
+"< 	c #A8A8A8",
+"[ 	c #9E9E9E",
+"} 	c #898989",
+"| 	c #A9A9A9",
+"1 	c #797979",
+"2 	c #999999",
+"3 	c #C6C6C6",
+"4 	c #7D7D7D",
+"5 	c #ABABAB",
+"6 	c #767676",
+"7 	c #E1C361",
+"8 	c #A8A088",
+"9 	c #919191",
+"0 	c #8E8E8E",
+"a 	c #DCB95A",
+"b 	c #DFB855",
+"c 	c #DEB551",
+"d 	c #DDB14D",
+"e 	c #DCAD49",
+"f 	c #D7A846",
+"g 	c #787878",
+"h 	c #8D7E65",
+"i 	c #D89931",
+"j 	c #E1C260",
+"k 	c #FCF3C9",
+"l 	c #FDF3CB",
+"m 	c #FEF6D4",
+"n 	c #FFF6D7",
+"o 	c #FFF4D8",
+"p 	c #FFF8E0",
+"q 	c #FFF8DF",
+"r 	c #FFF5DA",
+"s 	c #FCF1CD",
+"t 	c #76A942",
+"u 	c #659F31",
+"v 	c #FAEBBD",
+"w 	c #D6932B",
+"x 	c #E0BF5C",
+"y 	c #FCF3C8",
+"z 	c #F9DF75",
+"A 	c #FDE689",
+"B 	c #FFE795",
+"C 	c #FFE59A",
+"D 	c #FFEEAA",
+"E 	c #FFEDA8",
+"F 	c #FFE399",
+"G 	c #F9D574",
+"H 	c #6EA334",
+"I 	c #81B35A",
+"J 	c #579828",
+"K 	c #D58D24",
+"L 	c #DFBB58",
+"M 	c #FCF1C7",
+"N 	c #F9DC6F",
+"O 	c #EDBB56",
+"P 	c #EFBD61",
+"Q 	c #FFE79B",
+"R 	c #6FA53D",
+"S 	c #6FA337",
+"T 	c #69A234",
+"U 	c #639D2F",
+"V 	c #7CAF55",
+"W 	c #AACB91",
+"X 	c #74AB4F",
+"Y 	c #478F17",
+"Z 	c #DEB753",
+"` 	c #FCF0C6",
+" .	c #F8D96A",
+"..	c #FDE27C",
+"+.	c #FFE890",
+"@.	c #FFE999",
+"#.	c #6BA337",
+"$.	c #B0CE96",
+"%.	c #ADCD94",
+"&.	c #A8CB90",
+"*.	c #90BC74",
+"=.	c #A1C78A",
+"-.	c #68A546",
+";.	c #358707",
+">.	c #DDB24E",
+",.	c #FBEFC3",
+"'.	c #F8D665",
+").	c #ECB64C",
+"!.	c #EFBD5A",
+"~.	c #FFEB95",
+"{.	c #639F31",
+"].	c #8EBA6F",
+"^.	c #89B86B",
+"/.	c #85B666",
+"(.	c #80B361",
+"_.	c #82B567",
+":.	c #98C283",
+"<.	c #5CA03C",
+"[.	c #257F00",
+"}.	c #FBEEC1",
+"|.	c #F7D35F",
+"1.	c #FCDB6C",
+"2.	c #FFE57F",
+"3.	c #FFED8F",
+"4.	c #5B9B29",
+"5.	c #A9CA90",
+"6.	c #A5C88D",
+"7.	c #A1C68A",
+"8.	c #9EC588",
+"9.	c #85B66A",
+"0.	c #97C282",
+"a.	c #66A548",
+"b.	c #217D00",
+"c.	c #DBA843",
+"d.	c #FBECBF",
+"e.	c #F5CF59",
+"f.	c #ECB041",
+"g.	c #EFBA4E",
+"h.	c #EFC25A",
+"i.	c #529721",
+"j.	c #4A911C",
+"k.	c #448F15",
+"l.	c #3C8B0F",
+"m.	c #5E9F3A",
+"n.	c #96C180",
+"o.	c #62A346",
+"p.	c #3F7C02",
+"q.	c #DAA33D",
+"r.	c #FAEBBC",
+"s.	c #FCEBBC",
+"t.	c #FEEEBF",
+"u.	c #FFF4C6",
+"v.	c #FFF8CE",
+"w.	c #FFFAD3",
+"x.	c #FFF8D0",
+"y.	c #FFF2C7",
+"z.	c #FCE9BA",
+"A.	c #3B8B0F",
+"B.	c #5FA143",
+"C.	c #4A9023",
+"D.	c #CB7105",
+"E.	c #D99D36",
+"F.	c #D7942C",
+"G.	c #D69028",
+"H.	c #D58C23",
+"I.	c #D4881E",
+"J.	c #D3841A",
+"K.	c #D28015",
+"L.	c #D17C11",
+"M.	c #D1790E",
+"N.	c #2F7C01",
+"O.	c #1E7B03",
+"P.	c #CC7004",
+"Q.	c #CE6E01",
+"        . + @ # $ %             ",
+"      & * = - = ; > ,           ",
+"    ' ) ! ' ~ { $ ] ] ^         ",
+"    / ( _         : < [         ",
+"  @ ) '             } | 1       ",
+"  2 3 %             4 5 6       ",
+"7 8 9 0 a b c d e f g 6 h i     ",
+"j k l m n o p q r s t u v w     ",
+"x y z A B C D E F G H I J K     ",
+"L M N O P Q R S T U V W X Y     ",
+"Z `  ...+. at .#.$.%.W &.*.=.-.;.  ",
+">.,.'.).!.~.{.%.].^./.(._.:.<.[.",
+"e }.|.1.2.3.4.5.6.7.8.9.0.a.b.  ",
+"c.d.e.f.g.h.i.j.k.l.m.n.o.p.    ",
+"q.r.s.t.u.v.w.x.y.z.A.B.C.D.    ",
+"E.i F.G.H.I.J.K.L.M.N.O.P.Q.    "};
diff --git a/icons/vector.xpm b/icons/vector.xpm
new file mode 100644
index 0000000..ca71d1b
--- /dev/null
+++ b/icons/vector.xpm
@@ -0,0 +1,195 @@
+/* XPM */
+static const char * vector_xpm[] = {
+"16 16 176 2",
+"  	c None",
+". 	c #D8B24B",
+"+ 	c #D7B04A",
+"@ 	c #D8B44D",
+"# 	c #D7B24B",
+"$ 	c #EAD59C",
+"% 	c #E7CC88",
+"& 	c #D5AC45",
+"* 	c #D4AA44",
+"= 	c #D8B44C",
+"- 	c #E5CF92",
+"; 	c #FCF8E6",
+"> 	c #FEF6E3",
+", 	c #F2DDAF",
+"' 	c #F7E4B2",
+") 	c #E1C072",
+"! 	c #D1A43F",
+"~ 	c #D9B54E",
+"{ 	c #E0C67E",
+"] 	c #F7EED1",
+"^ 	c #FFFFF6",
+"/ 	c #FFFEF0",
+"( 	c #FBEDCB",
+"_ 	c #DAAD50",
+": 	c #F7D78B",
+"< 	c #F9E1AA",
+"[ 	c #F2D695",
+"} 	c #DBB262",
+"| 	c #CE9D39",
+"1 	c #D9B74F",
+"2 	c #D9B54D",
+"3 	c #EDD9A5",
+"4 	c #F5EBD2",
+"5 	c #EDDEBE",
+"6 	c #DEC995",
+"7 	c #DBC389",
+"8 	c #D6B870",
+"9 	c #DDB969",
+"0 	c #F5D790",
+"a 	c #F5CF7F",
+"b 	c #F8DB9D",
+"c 	c #FAE3AA",
+"d 	c #ECCA84",
+"e 	c #D5A651",
+"f 	c #CB9532",
+"g 	c #FEF8E1",
+"h 	c #F9EBCD",
+"i 	c #EDD292",
+"j 	c #EBCC84",
+"k 	c #E5BF6F",
+"l 	c #DBB156",
+"m 	c #C8943B",
+"n 	c #FAECCE",
+"o 	c #FFF5D9",
+"p 	c #FFEAB9",
+"q 	c #FEDF95",
+"r 	c #FFD577",
+"s 	c #FFE4A5",
+"t 	c #FBDC84",
+"u 	c #C9922F",
+"v 	c #FDF8E2",
+"w 	c #FFF3D4",
+"x 	c #FAE4B0",
+"y 	c #F1CF86",
+"z 	c #F5D07F",
+"A 	c #F5D078",
+"B 	c #E4B14C",
+"C 	c #FFE9B6",
+"D 	c #FFE19B",
+"E 	c #FED678",
+"F 	c #F5BD40",
+"G 	c #E9B53D",
+"H 	c #F1D590",
+"I 	c #C88F2D",
+"J 	c #D6B049",
+"K 	c #FDF6E2",
+"L 	c #FFF4DA",
+"M 	c #FFF3D5",
+"N 	c #FFEBBD",
+"O 	c #F7D589",
+"P 	c #F5C969",
+"Q 	c #E9B44C",
+"R 	c #FBDA8D",
+"S 	c #FFDC8C",
+"T 	c #F9C448",
+"U 	c #ECB638",
+"V 	c #E8BF48",
+"W 	c #E8BB4F",
+"X 	c #F0D08C",
+"Y 	c #C78D2B",
+"Z 	c #D5AD47",
+"` 	c #FCF6E2",
+" .	c #FFF4D7",
+"..	c #FFF2CE",
+"+.	c #FFEFC8",
+"@.	c #FFEBBA",
+"#.	c #FBDB92",
+"$.	c #F1C156",
+"%.	c #F9C248",
+"&.	c #F0BD3B",
+"*.	c #ECC547",
+"=.	c #E9BD45",
+"-.	c #E6B542",
+";.	c #E6B147",
+">.	c #EECA88",
+",.	c #C68A28",
+"'.	c #FFF0C9",
+").	c #FFEDBE",
+"!.	c #FFEAB3",
+"~.	c #FFE7AD",
+"{.	c #FED97C",
+"].	c #EFC748",
+"^.	c #EAC443",
+"/.	c #E8BE43",
+"(.	c #E6B53F",
+"_.	c #E3AB3A",
+":.	c #E1A740",
+"<.	c #ECC583",
+"[.	c #C58726",
+"}.	c #D3A842",
+"|.	c #FEFBE7",
+"1.	c #FFF6DD",
+"2.	c #FFEFC1",
+"3.	c #FFEBB7",
+"4.	c #FFE8AB",
+"5.	c #FFE4A4",
+"6.	c #FEE196",
+"7.	c #EBC648",
+"8.	c #E9BD40",
+"9.	c #E6B43D",
+"0.	c #E2A938",
+"a.	c #DE9F32",
+"b.	c #E6B66B",
+"c.	c #EEC483",
+"d.	c #C48524",
+"e.	c #D2A540",
+"f.	c #DCBD77",
+"g.	c #F6E5BF",
+"h.	c #FFF6DB",
+"i.	c #FFEEC1",
+"j.	c #FFE5A5",
+"k.	c #FFE39F",
+"l.	c #FEE194",
+"m.	c #EAC146",
+"n.	c #E6B53A",
+"o.	c #E2AA37",
+"p.	c #E5AF56",
+"q.	c #EDC687",
+"r.	c #E4B374",
+"s.	c #CA904A",
+"t.	c #C38322",
+"u.	c #E0C07D",
+"v.	c #FCEEC7",
+"w.	c #FFF2CC",
+"x.	c #FFE8A8",
+"y.	c #FEE094",
+"z.	c #E7BA41",
+"A.	c #E4B145",
+"B.	c #EFCA8A",
+"C.	c #EBC182",
+"D.	c #D09753",
+"E.	c #C38423",
+"F.	c #CC9834",
+"G.	c #E5C482",
+"H.	c #FFF4CC",
+"I.	c #FFEFC4",
+"J.	c #F1D28B",
+"K.	c #F0CE8A",
+"L.	c #D7A45F",
+"M.	c #C48625",
+"N.	c #C9902E",
+"O.	c #C88E2C",
+"P.	c #EBCD8F",
+"Q.	c #E2B76F",
+"R.	c #C88E40",
+"S.	c #C58928",
+"              . +               ",
+"          @ # $ % & *           ",
+"        = - ; > , ' ) !         ",
+"    ~ { ] ^ / ( _ : < [ } |     ",
+"1 2 3 4 5 6 7 8 9 0 a b c d e f ",
+"@ g h i j k l m n o p q r s t u ",
+"# v w x y z A B x C D E F G H I ",
+"J K L M N O P Q R S T U V W X Y ",
+"Z `  ...+. at .#.$.%.&.*.=.-.;.>.,.",
+"* ` w '.).!.~.{.].^./.(._.:.<.[.",
+"}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.",
+"e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.",
+"    | u.v.w.x.y.z.A.B.C.D.E.    ",
+"      F.f G.H.I.J.K.L.M.E.      ",
+"          N.O.P.Q.R.d.          ",
+"              S.[.              "};
diff --git a/mac_resource/Makefile.in b/mac_resource/Makefile.in
index 31bebb8..873571e 100644
--- a/mac_resource/Makefile.in
+++ b/mac_resource/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.12.2 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2012 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,23 +14,61 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \	]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -50,7 +88,6 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = mac_resource
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -58,10 +95,23 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
 SOURCES =
 DIST_SOURCES =
 am__can_run_installinfo = \
@@ -69,9 +119,12 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -112,13 +165,17 @@ LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBFREEXL_CFLAGS = @LIBFREEXL_CFLAGS@
 LIBFREEXL_LIBS = @LIBFREEXL_LIBS@
-LIBGAIAGRAPHICS_CFLAGS = @LIBGAIAGRAPHICS_CFLAGS@
-LIBGAIAGRAPHICS_LIBS = @LIBGAIAGRAPHICS_LIBS@
+LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
+LIBLZMA_LIBS = @LIBLZMA_LIBS@
 LIBOBJS = @LIBOBJS@
+LIBRASTERLITE2_CFLAGS = @LIBRASTERLITE2_CFLAGS@
+LIBRASTERLITE2_LIBS = @LIBRASTERLITE2_LIBS@
 LIBS = @LIBS@
 LIBSPATIALITE_CFLAGS = @LIBSPATIALITE_CFLAGS@
 LIBSPATIALITE_LIBS = @LIBSPATIALITE_LIBS@
 LIBTOOL = @LIBTOOL@
+LIBWEBP_CFLAGS = @LIBWEBP_CFLAGS@
+LIBWEBP_LIBS = @LIBWEBP_LIBS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -152,7 +209,7 @@ SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 VERSION = @VERSION@
-WX_CONFIG = @WX_CONFIG@
+WXCONFIG = @WXCONFIG@
 WX_LIBS = @WX_LIBS@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
@@ -223,7 +280,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu mac_resource/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu mac_resource/Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -247,11 +303,9 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
-tags: TAGS
-TAGS:
+tags TAGS:
 
-ctags: CTAGS
-CTAGS:
+ctags CTAGS:
 
 cscope cscopelist:
 
@@ -389,15 +443,18 @@ uninstall-am:
 .MAKE: install-am install-strip
 
 .PHONY: all all-am check check-am clean clean-generic clean-libtool \
-	distclean distclean-generic distclean-libtool distdir dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-dvi install-dvi-am \
-	install-exec install-exec-am install-html install-html-am \
-	install-info install-info-am install-man install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/win_resource/Makefile.in b/win_resource/Makefile.in
index 0209816..69f03e8 100644
--- a/win_resource/Makefile.in
+++ b/win_resource/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.12.2 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2012 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,23 +14,61 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \	]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -50,7 +88,6 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = win_resource
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -58,10 +95,23 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
 SOURCES =
 DIST_SOURCES =
 am__can_run_installinfo = \
@@ -69,9 +119,12 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -112,13 +165,17 @@ LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBFREEXL_CFLAGS = @LIBFREEXL_CFLAGS@
 LIBFREEXL_LIBS = @LIBFREEXL_LIBS@
-LIBGAIAGRAPHICS_CFLAGS = @LIBGAIAGRAPHICS_CFLAGS@
-LIBGAIAGRAPHICS_LIBS = @LIBGAIAGRAPHICS_LIBS@
+LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
+LIBLZMA_LIBS = @LIBLZMA_LIBS@
 LIBOBJS = @LIBOBJS@
+LIBRASTERLITE2_CFLAGS = @LIBRASTERLITE2_CFLAGS@
+LIBRASTERLITE2_LIBS = @LIBRASTERLITE2_LIBS@
 LIBS = @LIBS@
 LIBSPATIALITE_CFLAGS = @LIBSPATIALITE_CFLAGS@
 LIBSPATIALITE_LIBS = @LIBSPATIALITE_LIBS@
 LIBTOOL = @LIBTOOL@
+LIBWEBP_CFLAGS = @LIBWEBP_CFLAGS@
+LIBWEBP_LIBS = @LIBWEBP_LIBS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -152,7 +209,7 @@ SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 VERSION = @VERSION@
-WX_CONFIG = @WX_CONFIG@
+WXCONFIG = @WXCONFIG@
 WX_LIBS = @WX_LIBS@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
@@ -223,7 +280,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu win_resource/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu win_resource/Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -247,11 +303,9 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
-tags: TAGS
-TAGS:
+tags TAGS:
 
-ctags: CTAGS
-CTAGS:
+ctags CTAGS:
 
 cscope cscopelist:
 
@@ -389,15 +443,18 @@ uninstall-am:
 .MAKE: install-am install-strip
 
 .PHONY: all all-am check check-am clean clean-generic clean-libtool \
-	distclean distclean-generic distclean-libtool distdir dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-dvi install-dvi-am \
-	install-exec install-exec-am install-html install-html-am \
-	install-info install-info-am install-man install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.

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



More information about the Pkg-grass-devel mailing list